Commit 5ee9cf87 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[inspector] Fix handling of on-heap TypedArrays in queryObjects()

On-heap TypedArrays have empty ArrayBuffers that are not supposed to be
accessed directly. Such ArrayBuffers materialize properly when accessed
via their TypedArrays.

The queryObjects() sidesteps the bottleneck and finds empty ArrayBuffers
by iterating the heap. When preview TypedArrays are constructed for the
found ArrayBuffers, they get nullptr data pointers.

This CL converts all on-heap TypedArrays into off-heap TypedArrays in
queryObjects to make sure that all found ArrayBuffers are valid.

Bug: chromium:992442
Change-Id: Ie77d1e75aa2007b4a976c72206b9a4e215c9ef53
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2150601
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67174}
parent 6210bc82
......@@ -216,14 +216,27 @@ void HeapProfiler::QueryObjects(Handle<Context> context,
debug::QueryObjectPredicate* predicate,
PersistentValueVector<v8::Object>* objects) {
{
CombinedHeapObjectIterator function_heap_iterator(
HandleScope handle_scope(isolate());
std::vector<Handle<JSTypedArray>> on_heap_typed_arrays;
CombinedHeapObjectIterator heap_iterator(
heap(), HeapObjectIterator::kFilterUnreachable);
for (HeapObject heap_obj = function_heap_iterator.Next();
!heap_obj.is_null(); heap_obj = function_heap_iterator.Next()) {
for (HeapObject heap_obj = heap_iterator.Next(); !heap_obj.is_null();
heap_obj = heap_iterator.Next()) {
if (heap_obj.IsFeedbackVector()) {
FeedbackVector::cast(heap_obj).ClearSlots(isolate());
} else if (heap_obj.IsJSTypedArray() &&
JSTypedArray::cast(heap_obj).is_on_heap()) {
// Cannot call typed_array->GetBuffer() here directly because it may
// trigger GC. Defer that call by collecting the object in a vector.
on_heap_typed_arrays.push_back(
handle(JSTypedArray::cast(heap_obj), isolate()));
}
}
for (auto& typed_array : on_heap_typed_arrays) {
// Convert the on-heap typed array into off-heap typed array, so that
// its ArrayBuffer becomes valid and can be returned in the result.
typed_array->GetBuffer();
}
}
// We should return accurate information about live objects, so we need to
// collect all garbage first.
......
......@@ -98,6 +98,9 @@ Dump each object constructor name.
Running test: testQueryObjectsWithFeedbackVector
Before/After difference: 1
Running test: testQueryObjectsWithArrayBuffer
Test that queryObjects does not crash for on-heap TypedArrays
Running test: testWithObjectGroup
Query for Array.prototype 3 times
Results since initial: 0
......
......@@ -147,6 +147,34 @@ InspectorTest.runAsyncTestSuite([
session.disconnect();
},
async function testQueryObjectsWithArrayBuffer() {
let contextGroup = new InspectorTest.ContextGroup();
let session = contextGroup.connect();
let Protocol = session.Protocol;
await Protocol.Runtime.evaluate({
expression: 'new Int8Array(32)',
});
let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
expression: 'ArrayBuffer.prototype'
});
let {result:{objects}} = await session.Protocol.Runtime.queryObjects({
prototypeObjectId: objectId
});
let {result:{result: properties}} = await session.Protocol.Runtime.getProperties({
objectId: objects.objectId,
ownProperties: true,
generatePreview: true
});
await session.Protocol.Runtime.getProperties({
objectId: properties[0].value.objectId,
ownProperties: true,
generatePreview: true
});
InspectorTest.log('Test that queryObjects does not crash for on-heap TypedArrays');
session.disconnect();
},
async function testWithObjectGroup() {
let contextGroup = new InspectorTest.ContextGroup();
let session = contextGroup.connect();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment