[debug] Implement stepping out of async functions in the debugger.

Previously the inspector was trying to handle step-out for async
functions by annotating the async stacks, but this was merely a
hack and didn't work reliably

(a) when the async caller that is `await`ing the result of the
    callee was still in the synchronous part (because then there
    was no async task yet in the inspector), or
(b) not at all when the async stack tracking wasn't enabled or the
    maximum async stack depth was too small.

This CL replaces that hack with a pragmatic solution inside the
V8 debugger, where upon `await` we memorize the async function
object of the caller on the outer promise of the callee, and when
stepping out of the callee we check whether the returned promise
has a memorized async function object and if so, we schedule that
to resume.

This CL thereby effectively reverts https://crrev.com/c/1054618
and replaces it with a V8 debug solution, and thereby further
reduces the (memory) overhead of an AsyncStackTrace.

Fixed: chromium:1246867
Bug: v8:6161, v8:7753, chromium:1277451, chromium:1280519
Change-Id: I6aa79e90f49d204f66bfd37e7a328c7fb8d635b1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3439865
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78990}
This commit is contained in:
Benedikt Meurer 2022-02-07 16:46:01 +01:00 committed by V8 LUCI CQ
parent 4c89a32ff7
commit 536e96cc1a
11 changed files with 193 additions and 197 deletions

View File

@ -138,9 +138,9 @@ TNode<Object> AsyncBuiltinsAssembler::Await(
Goto(&if_instrumentation_done);
BIND(&if_instrumentation);
{
var_throwaway =
CallRuntime(Runtime::kDebugAsyncFunctionSuspended, native_context,
value, outer_promise, on_reject, is_predicted_as_caught);
var_throwaway = CallRuntime(Runtime::kDebugAsyncFunctionSuspended,
native_context, value, outer_promise, on_reject,
generator, is_predicted_as_caught);
Goto(&if_instrumentation_done);
}
BIND(&if_instrumentation_done);

View File

@ -1182,8 +1182,8 @@ void Debug::PrepareStep(StepAction step_action) {
// Clear last position info. For stepping out it does not matter.
thread_local_.last_statement_position_ = kNoSourcePosition;
thread_local_.last_frame_count_ = -1;
if (!shared.is_null() && !location.IsReturnOrSuspend() &&
!IsBlackboxed(shared)) {
if (!shared.is_null()) {
if (!location.IsReturnOrSuspend() && !IsBlackboxed(shared)) {
// At not return position we flood return positions with one shots and
// will repeat StepOut automatically at next break.
thread_local_.target_frame_count_ = current_frame_count;
@ -1191,6 +1191,23 @@ void Debug::PrepareStep(StepAction step_action) {
FloodWithOneShot(shared, true);
return;
}
if (IsAsyncFunction(shared->kind())) {
// Stepping out of an async function whose implicit promise is awaited
// by some other async function, should resume the latter. The return
// value here is either a JSPromise or a JSGeneratorObject (for the
// initial yield of async generators).
Handle<JSReceiver> return_value(
JSReceiver::cast(thread_local_.return_value_), isolate_);
Handle<Object> awaited_by = JSReceiver::GetDataProperty(
return_value, isolate_->factory()->promise_awaited_by_symbol());
if (awaited_by->IsJSGeneratorObject()) {
DCHECK(!has_suspended_generator());
thread_local_.suspended_generator_ = *awaited_by;
ClearStepping();
return;
}
}
}
// Skip the current frame, find the first frame we want to step out to
// and deoptimize every frame along the way.
bool in_current_frame = true;

View File

@ -444,6 +444,7 @@
V(_, promise_debug_message_symbol) \
V(_, promise_forwarding_handler_symbol) \
V(_, promise_handled_by_symbol) \
V(_, promise_awaited_by_symbol) \
V(_, regexp_result_names_symbol) \
V(_, regexp_result_regexp_input_symbol) \
V(_, regexp_result_regexp_last_index_symbol) \

View File

@ -252,7 +252,6 @@ void V8Debugger::stepIntoStatement(int targetContextGroupId,
bool breakOnAsyncCall) {
DCHECK(isPaused());
DCHECK(targetContextGroupId);
if (asyncStepOutOfFunction(targetContextGroupId, true)) return;
m_targetContextGroupId = targetContextGroupId;
m_pauseOnAsyncCall = breakOnAsyncCall;
v8::debug::PrepareStep(m_isolate, v8::debug::StepInto);
@ -262,7 +261,6 @@ void V8Debugger::stepIntoStatement(int targetContextGroupId,
void V8Debugger::stepOverStatement(int targetContextGroupId) {
DCHECK(isPaused());
DCHECK(targetContextGroupId);
if (asyncStepOutOfFunction(targetContextGroupId, true)) return;
m_targetContextGroupId = targetContextGroupId;
v8::debug::PrepareStep(m_isolate, v8::debug::StepOver);
continueProgram(targetContextGroupId);
@ -271,48 +269,11 @@ void V8Debugger::stepOverStatement(int targetContextGroupId) {
void V8Debugger::stepOutOfFunction(int targetContextGroupId) {
DCHECK(isPaused());
DCHECK(targetContextGroupId);
if (asyncStepOutOfFunction(targetContextGroupId, false)) return;
m_targetContextGroupId = targetContextGroupId;
v8::debug::PrepareStep(m_isolate, v8::debug::StepOut);
continueProgram(targetContextGroupId);
}
bool V8Debugger::asyncStepOutOfFunction(int targetContextGroupId,
bool onlyAtReturn) {
v8::HandleScope handleScope(m_isolate);
auto iterator = v8::debug::StackTraceIterator::Create(m_isolate);
// When stepping through extensions code, it is possible that the
// iterator doesn't have any frames, since we exclude all frames
// that correspond to extension scripts.
if (iterator->Done()) return false;
bool atReturn = !iterator->GetReturnValue().IsEmpty();
iterator->Advance();
// Synchronous stack has more then one frame.
if (!iterator->Done()) return false;
// There is only one synchronous frame but we are not at return position and
// user requests stepOver or stepInto.
if (onlyAtReturn && !atReturn) return false;
// If we are inside async function, current async parent was captured when
// async function was suspended first time and we install that stack as
// current before resume async function. So it represents current async
// function.
auto current = currentAsyncParent();
if (!current) return false;
// Lookup for parent async function.
auto parent = current->parent();
if (parent.expired()) return false;
// Parent async stack will have suspended task id iff callee async function
// is awaiting current async function. We can make stepOut there only in this
// case.
void* parentTask =
std::shared_ptr<AsyncStackTrace>(parent)->suspendedTaskId();
if (!parentTask) return false;
m_targetContextGroupId = targetContextGroupId;
m_taskWithScheduledBreak = parentTask;
continueProgram(targetContextGroupId);
return true;
}
void V8Debugger::terminateExecution(
std::unique_ptr<TerminateExecutionCallback> callback) {
if (m_terminateExecutionCallback) {
@ -623,11 +584,6 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type,
break;
case v8::debug::kDebugAwait: {
asyncTaskScheduledForStack(toStringView("await"), task, false, true);
auto stackIt = m_asyncTaskStacks.find(task);
if (stackIt != m_asyncTaskStacks.end() && !stackIt->second.expired()) {
std::shared_ptr<AsyncStackTrace> stack(stackIt->second);
stack->setSuspendedTaskId(task);
}
break;
}
}
@ -1007,7 +963,6 @@ void V8Debugger::asyncTaskStartedForStack(void* task) {
AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task);
if (stackIt != m_asyncTaskStacks.end() && !stackIt->second.expired()) {
std::shared_ptr<AsyncStackTrace> stack(stackIt->second);
stack->setSuspendedTaskId(nullptr);
m_currentAsyncParent.push_back(stack);
} else {
m_currentAsyncParent.emplace_back();

View File

@ -197,7 +197,6 @@ class V8Debugger : public v8::debug::DebugDelegate,
int column) override;
int currentContextGroupId();
bool asyncStepOutOfFunction(int targetContextGroupId, bool onlyAtReturn);
bool hasScheduledBreakOnNextFunctionCall() const;

View File

@ -441,7 +441,6 @@ AsyncStackTrace::AsyncStackTrace(
std::shared_ptr<AsyncStackTrace> asyncParent,
const V8StackTraceId& externalParent)
: m_id(0),
m_suspendedTaskId(nullptr),
m_description(description),
m_frames(std::move(frames)),
m_asyncParent(std::move(asyncParent)),
@ -455,12 +454,6 @@ AsyncStackTrace::buildInspectorObject(V8Debugger* debugger,
maxAsyncDepth);
}
void AsyncStackTrace::setSuspendedTaskId(void* task) {
m_suspendedTaskId = task;
}
void* AsyncStackTrace::suspendedTaskId() const { return m_suspendedTaskId; }
uintptr_t AsyncStackTrace::store(V8Debugger* debugger,
std::shared_ptr<AsyncStackTrace> stack) {
if (stack->m_id) return stack->m_id;

View File

@ -123,16 +123,6 @@ class AsyncStackTrace {
std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObject(
V8Debugger* debugger, int maxAsyncDepth) const;
// If async stack has suspended task id, it means that at moment when we
// capture current stack trace we suspended corresponded asynchronous
// execution flow and it is possible to request pause for a momemnt when
// that flow is resumed.
// E.g. every time when we suspend async function we mark corresponded async
// stack as suspended and every time when this function is resumed we remove
// suspendedTaskId.
void setSuspendedTaskId(void* task);
void* suspendedTaskId() const;
const String16& description() const;
std::weak_ptr<AsyncStackTrace> parent() const;
bool isEmpty() const;
@ -149,7 +139,6 @@ class AsyncStackTrace {
const V8StackTraceId& externalParent);
uintptr_t m_id;
void* m_suspendedTaskId;
String16 m_description;
std::vector<std::shared_ptr<StackFrame>> m_frames;

View File

@ -819,12 +819,13 @@ RUNTIME_FUNCTION(Runtime_IncBlockCounter) {
}
RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionSuspended) {
DCHECK_EQ(4, args.length());
DCHECK_EQ(5, args.length());
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, outer_promise, 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject_handler, 2);
CONVERT_BOOLEAN_ARG_CHECKED(is_predicted_as_caught, 3);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 3);
CONVERT_BOOLEAN_ARG_CHECKED(is_predicted_as_caught, 4);
// Allocate the throwaway promise and fire the appropriate init
// hook for the throwaway promise (passing the {promise} as its
@ -853,6 +854,11 @@ RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionSuspended) {
outer_promise, StoreOrigin::kMaybeKeyed,
Just(ShouldThrow::kThrowOnError))
.Check();
Object::SetProperty(
isolate, promise, isolate->factory()->promise_awaited_by_symbol(),
generator, StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError))
.Check();
}
return *throwaway;

View File

@ -1,6 +1,6 @@
StepOut from return position of async function.
Running test: testStepInto
Running test: testStepIntoAtReturnPosition
p.then(() => 1);
#debugger;
return p;
@ -13,12 +13,12 @@ Running test: testStepInto
return p;#
}
await p;
p.then(() => #1);
debugger;
await foo();
#}
Running test: testStepOver
Running test: testStepOverAtReturnPosition
p.then(() => 1);
#debugger;
return p;
@ -31,13 +31,23 @@ Running test: testStepOver
return p;#
}
await p;
p.then(() => #1);
debugger;
await foo();
#}
Running test: testStepOutAtReturnPosition
p.then(() => 1);
#debugger;
return p;
await p;
p.then(() => 1#);
debugger;
#return p;
}
debugger;
return p;#
}
await foo();
#}
@ -49,18 +59,6 @@ Running test: testStepOut
#debugger;
return p;
debugger;
#return p;
}
debugger;
return p;#
}
await p;
p.then(() => #1);
debugger;
await foo();
#}

View File

@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(kozyatinskiy): on StepOut and probably StepOver at return position
// of async generator we should break at next instruction of resumed generator
// instead of next scheduled microtask.
let {session, contextGroup, Protocol} = InspectorTest.start('StepOut from return position of async function.');
contextGroup.addScript(`
@ -22,48 +18,90 @@ contextGroup.addScript(`
`);
session.setupScriptMap();
Protocol.Debugger.enable();
InspectorTest.runAsyncTestSuite([
async function testStepInto() {
async function testStepIntoAtReturnPosition() {
await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
]);
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.resume();
await Promise.all([
Protocol.Debugger.resume(),
evalPromise,
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
async function testStepOver() {
async function testStepOverAtReturnPosition() {
await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
]);
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepOver();
await Protocol.Debugger.stepOver();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepOver();
await Promise.all([
Protocol.Debugger.resume(),
evalPromise,
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
async function testStepOutAtReturnPosition() {
await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
]);
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepOver();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.resume();
await Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
await Protocol.Debugger.stepOut();
await logPauseLocation(await Protocol.Debugger.oncePaused());
await Promise.all([
Protocol.Debugger.resume(),
evalPromise,
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
async function testStepOut() {
await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
]);
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await Protocol.Debugger.stepOut();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepInto();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepOut();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.stepOut();
await logPauseLocation(await Protocol.Debugger.oncePaused());
Protocol.Debugger.resume();
await Promise.all([
Protocol.Debugger.resume(),
evalPromise,
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
]);

View File

@ -371,76 +371,76 @@ KNOWN_MAPS = {
("read_only_space", 0x033d9): (131, "BasicBlockCountersMarkerMap"),
("read_only_space", 0x0341d): (147, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x0351d): (161, "InterceptorInfoMap"),
("read_only_space", 0x05e39): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05e61): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05e89): (134, "CallableTaskMap"),
("read_only_space", 0x05eb1): (135, "CallbackTaskMap"),
("read_only_space", 0x05ed9): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05f01): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x05f29): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x05f51): (141, "AccessCheckInfoMap"),
("read_only_space", 0x05f79): (142, "AccessorInfoMap"),
("read_only_space", 0x05fa1): (143, "AccessorPairMap"),
("read_only_space", 0x05fc9): (144, "AliasedArgumentsEntryMap"),
("read_only_space", 0x05ff1): (145, "AllocationMementoMap"),
("read_only_space", 0x06019): (148, "AsmWasmDataMap"),
("read_only_space", 0x06041): (149, "AsyncGeneratorRequestMap"),
("read_only_space", 0x06069): (150, "BreakPointMap"),
("read_only_space", 0x06091): (151, "BreakPointInfoMap"),
("read_only_space", 0x060b9): (152, "CachedTemplateObjectMap"),
("read_only_space", 0x060e1): (154, "CallSiteInfoMap"),
("read_only_space", 0x06109): (155, "ClassPositionsMap"),
("read_only_space", 0x06131): (156, "DebugInfoMap"),
("read_only_space", 0x06159): (158, "ErrorStackDataMap"),
("read_only_space", 0x06181): (160, "FunctionTemplateRareDataMap"),
("read_only_space", 0x061a9): (162, "InterpreterDataMap"),
("read_only_space", 0x061d1): (163, "ModuleRequestMap"),
("read_only_space", 0x061f9): (164, "PromiseCapabilityMap"),
("read_only_space", 0x06221): (165, "PromiseReactionMap"),
("read_only_space", 0x06249): (166, "PropertyDescriptorObjectMap"),
("read_only_space", 0x06271): (167, "PrototypeInfoMap"),
("read_only_space", 0x06299): (168, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x062c1): (169, "ScriptMap"),
("read_only_space", 0x062e9): (170, "ScriptOrModuleMap"),
("read_only_space", 0x06311): (171, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x06339): (172, "StackFrameInfoMap"),
("read_only_space", 0x06361): (173, "TemplateObjectDescriptionMap"),
("read_only_space", 0x06389): (174, "Tuple2Map"),
("read_only_space", 0x063b1): (175, "WasmContinuationObjectMap"),
("read_only_space", 0x063d9): (176, "WasmExceptionTagMap"),
("read_only_space", 0x06401): (177, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x06429): (196, "SloppyArgumentsElementsMap"),
("read_only_space", 0x06451): (231, "DescriptorArrayMap"),
("read_only_space", 0x06479): (219, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x064a1): (217, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x064c9): (220, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x064f1): (218, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x06519): (250, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x06541): (197, "TurbofanBitsetTypeMap"),
("read_only_space", 0x06569): (201, "TurbofanUnionTypeMap"),
("read_only_space", 0x06591): (200, "TurbofanRangeTypeMap"),
("read_only_space", 0x065b9): (198, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x065e1): (199, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x06609): (246, "InternalClassMap"),
("read_only_space", 0x06631): (257, "SmiPairMap"),
("read_only_space", 0x06659): (256, "SmiBoxMap"),
("read_only_space", 0x06681): (225, "ExportedSubClassBaseMap"),
("read_only_space", 0x066a9): (226, "ExportedSubClassMap"),
("read_only_space", 0x066d1): (202, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x066f9): (203, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x06721): (195, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x06749): (247, "InternalClassWithStructElementsMap"),
("read_only_space", 0x06771): (227, "ExportedSubClass2Map"),
("read_only_space", 0x06799): (258, "SortStateMap"),
("read_only_space", 0x067c1): (146, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x067e9): (146, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x06811): (137, "LoadHandler1Map"),
("read_only_space", 0x06839): (137, "LoadHandler2Map"),
("read_only_space", 0x06861): (137, "LoadHandler3Map"),
("read_only_space", 0x06889): (138, "StoreHandler0Map"),
("read_only_space", 0x068b1): (138, "StoreHandler1Map"),
("read_only_space", 0x068d9): (138, "StoreHandler2Map"),
("read_only_space", 0x06901): (138, "StoreHandler3Map"),
("read_only_space", 0x05e49): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05e71): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05e99): (134, "CallableTaskMap"),
("read_only_space", 0x05ec1): (135, "CallbackTaskMap"),
("read_only_space", 0x05ee9): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05f11): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x05f39): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x05f61): (141, "AccessCheckInfoMap"),
("read_only_space", 0x05f89): (142, "AccessorInfoMap"),
("read_only_space", 0x05fb1): (143, "AccessorPairMap"),
("read_only_space", 0x05fd9): (144, "AliasedArgumentsEntryMap"),
("read_only_space", 0x06001): (145, "AllocationMementoMap"),
("read_only_space", 0x06029): (148, "AsmWasmDataMap"),
("read_only_space", 0x06051): (149, "AsyncGeneratorRequestMap"),
("read_only_space", 0x06079): (150, "BreakPointMap"),
("read_only_space", 0x060a1): (151, "BreakPointInfoMap"),
("read_only_space", 0x060c9): (152, "CachedTemplateObjectMap"),
("read_only_space", 0x060f1): (154, "CallSiteInfoMap"),
("read_only_space", 0x06119): (155, "ClassPositionsMap"),
("read_only_space", 0x06141): (156, "DebugInfoMap"),
("read_only_space", 0x06169): (158, "ErrorStackDataMap"),
("read_only_space", 0x06191): (160, "FunctionTemplateRareDataMap"),
("read_only_space", 0x061b9): (162, "InterpreterDataMap"),
("read_only_space", 0x061e1): (163, "ModuleRequestMap"),
("read_only_space", 0x06209): (164, "PromiseCapabilityMap"),
("read_only_space", 0x06231): (165, "PromiseReactionMap"),
("read_only_space", 0x06259): (166, "PropertyDescriptorObjectMap"),
("read_only_space", 0x06281): (167, "PrototypeInfoMap"),
("read_only_space", 0x062a9): (168, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x062d1): (169, "ScriptMap"),
("read_only_space", 0x062f9): (170, "ScriptOrModuleMap"),
("read_only_space", 0x06321): (171, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x06349): (172, "StackFrameInfoMap"),
("read_only_space", 0x06371): (173, "TemplateObjectDescriptionMap"),
("read_only_space", 0x06399): (174, "Tuple2Map"),
("read_only_space", 0x063c1): (175, "WasmContinuationObjectMap"),
("read_only_space", 0x063e9): (176, "WasmExceptionTagMap"),
("read_only_space", 0x06411): (177, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x06439): (196, "SloppyArgumentsElementsMap"),
("read_only_space", 0x06461): (231, "DescriptorArrayMap"),
("read_only_space", 0x06489): (219, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x064b1): (217, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x064d9): (220, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x06501): (218, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x06529): (250, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x06551): (197, "TurbofanBitsetTypeMap"),
("read_only_space", 0x06579): (201, "TurbofanUnionTypeMap"),
("read_only_space", 0x065a1): (200, "TurbofanRangeTypeMap"),
("read_only_space", 0x065c9): (198, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x065f1): (199, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x06619): (246, "InternalClassMap"),
("read_only_space", 0x06641): (257, "SmiPairMap"),
("read_only_space", 0x06669): (256, "SmiBoxMap"),
("read_only_space", 0x06691): (225, "ExportedSubClassBaseMap"),
("read_only_space", 0x066b9): (226, "ExportedSubClassMap"),
("read_only_space", 0x066e1): (202, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x06709): (203, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x06731): (195, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x06759): (247, "InternalClassWithStructElementsMap"),
("read_only_space", 0x06781): (227, "ExportedSubClass2Map"),
("read_only_space", 0x067a9): (258, "SortStateMap"),
("read_only_space", 0x067d1): (146, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x067f9): (146, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x06821): (137, "LoadHandler1Map"),
("read_only_space", 0x06849): (137, "LoadHandler2Map"),
("read_only_space", 0x06871): (137, "LoadHandler3Map"),
("read_only_space", 0x06899): (138, "StoreHandler0Map"),
("read_only_space", 0x068c1): (138, "StoreHandler1Map"),
("read_only_space", 0x068e9): (138, "StoreHandler2Map"),
("read_only_space", 0x06911): (138, "StoreHandler3Map"),
("map_space", 0x02149): (1057, "ExternalMap"),
("map_space", 0x02171): (2114, "JSMessageObjectMap"),
}