[static-roots] Allow creating isolates from existing r/o snapshot

This adds the ability to create an isolate from scratch, except the
read only roots, which are initialized from a read_only_data snapshot.
To do this we split the heap setup in a read/only part and the rest.
The goal of these changes is to later support writing serializer tests,
even if the read only roots are static and have to be loaded from a
fixed snapshot.

Bug: v8:13466
Change-Id: I078695b95710e5281da013ca0c08af0e153b4725
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4037271
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Olivier Flückiger <olivf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84750}
This commit is contained in:
Olivier Flückiger 2022-12-09 10:58:25 +00:00 committed by V8 LUCI CQ
parent 710f2a4da2
commit 331c577e1d
13 changed files with 460 additions and 238 deletions

View File

@ -4026,6 +4026,13 @@ bool Isolate::InitWithoutSnapshot() {
return Init(nullptr, nullptr, nullptr, false);
}
bool Isolate::InitWithReadOnlySnapshot(SnapshotData* read_only_snapshot_data) {
DCHECK_NOT_NULL(read_only_snapshot_data);
// Without external code space builtin code objects are alocated in ro space
DCHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
return Init(nullptr, read_only_snapshot_data, nullptr, false);
}
bool Isolate::InitWithSnapshot(SnapshotData* startup_snapshot_data,
SnapshotData* read_only_snapshot_data,
SnapshotData* shared_heap_snapshot_data,
@ -4138,10 +4145,13 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
CHECK_EQ(V8HeapCompressionScheme::base(), cage_base());
#endif // V8_COMPRESS_POINTERS_IN_SHARED_CAGE
const bool create_heap_objects = (read_only_snapshot_data == nullptr);
// We either have all or none.
const bool create_heap_objects = (shared_heap_snapshot_data == nullptr);
const bool setup_up_existing_read_only_roots =
create_heap_objects && (read_only_snapshot_data != nullptr);
// We either have both or none.
DCHECK_EQ(create_heap_objects, startup_snapshot_data == nullptr);
DCHECK_EQ(create_heap_objects, shared_heap_snapshot_data == nullptr);
DCHECK_IMPLIES(setup_up_existing_read_only_roots,
startup_snapshot_data == nullptr);
// Code space setup requires the permissions to be set to default state.
RwxMemoryWriteScope::SetDefaultPermissionsForNewThread();
@ -4294,6 +4304,28 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
string_forwarding_table_ = shared_heap_isolate()->string_forwarding_table_;
}
// If we create an isolate from scratch, but based on existing read only
// roots, then we need to populate the string cache with its strings.
if (setup_up_existing_read_only_roots) {
HandleScope scope(this);
ReadOnlyHeapObjectIterator iterator(read_only_heap());
for (HeapObject object = iterator.Next(); !object.is_null();
object = iterator.Next()) {
if (object.IsInternalizedString()) {
auto s = String::cast(object);
Handle<String> str(s, this);
StringTableInsertionKey key(
this, str, DeserializingUserCodeOption::kNotDeserializingUserCode);
auto result = string_table()->LookupKey(this, &key);
// Since this is startup, there should be no duplicate entries in the
// string table, and the lookup should unconditionally add the given
// string.
DCHECK_EQ(*result, *str);
USE(result);
}
}
}
if (V8_SHORT_BUILTIN_CALLS_BOOL && v8_flags.short_builtin_calls) {
#if defined(V8_OS_ANDROID)
// On Android, the check is not operative to detect memory, and re-embedded
@ -4438,7 +4470,9 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
CodePageCollectionMemoryModificationScope modification_scope(heap());
if (create_heap_objects) {
read_only_heap_->OnCreateHeapObjectsComplete(this);
if (!setup_up_existing_read_only_roots) {
read_only_heap_->OnCreateHeapObjectsComplete(this);
}
} else {
SharedHeapDeserializer shared_heap_deserializer(
this, shared_heap_snapshot_data, can_rehash);

View File

@ -661,6 +661,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
bool InitializeCounters(); // Returns false if already initialized.
bool InitWithoutSnapshot();
bool InitWithReadOnlySnapshot(SnapshotData* read_only_snapshot_data);
bool InitWithSnapshot(SnapshotData* startup_snapshot_data,
SnapshotData* read_only_snapshot_data,
SnapshotData* shared_heap_snapshot_data,

View File

@ -2382,9 +2382,13 @@ Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
}
Handle<HeapNumber> Factory::NewHeapNumberForCodeAssembler(double value) {
return CanAllocateInReadOnlySpace()
? NewHeapNumber<AllocationType::kReadOnly>(value)
: NewHeapNumber<AllocationType::kOld>(value);
ReadOnlyRoots roots(isolate());
auto num = roots.FindHeapNumber(value);
if (!num.is_null()) return num;
// Add known HeapNumber constants to the read only roots. This ensures
// r/o snapshots to be deterministic.
DCHECK(!CanAllocateInReadOnlySpace());
return NewHeapNumber<AllocationType::kOld>(value);
}
Handle<JSObject> Factory::NewError(Handle<JSFunction> constructor,

View File

@ -667,7 +667,8 @@ class Heap {
// Support for the API.
//
void CreateApiObjects();
void CreateReadOnlyApiObjects();
void CreateMutableApiObjects();
// Implements the corresponding V8 API function.
bool IdleNotification(double deadline_in_seconds);
@ -810,7 +811,8 @@ class Heap {
// Bootstraps the object heap with the core set of objects required to run.
// Returns whether it succeeded.
bool CreateHeapObjects();
bool CreateReadOnlyHeapObjects();
bool CreateMutableHeapObjects();
// Create ObjectStats if live_object_stats_ or dead_object_stats_ are nullptr.
void CreateObjectStats();
@ -1810,9 +1812,10 @@ class Heap {
inline void UpdateOldSpaceLimits();
bool CreateInitialMaps();
bool CreateInitialReadOnlyMaps();
void CreateInternalAccessorInfoObjects();
void CreateInitialObjects();
void CreateInitialMutableObjects();
void CreateInitialReadOnlyObjects();
// Zaps the memory of a code object.
V8_EXPORT_PRIVATE void ZapCodeObject(Address start_address,
@ -2046,7 +2049,8 @@ class Heap {
// Allocates a JS Map in the heap.
V8_WARN_UNUSED_RESULT AllocationResult
AllocateMap(InstanceType instance_type, int instance_size,
AllocateMap(AllocationType allocation_type, InstanceType instance_type,
int instance_size,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
int inobject_properties = 0);

View File

@ -145,7 +145,8 @@ ReadOnlyHeap* ReadOnlyHeap::CreateInitalHeapForBootstrapping(
} else {
std::unique_ptr<SoleReadOnlyHeap> sole_ro_heap(
new SoleReadOnlyHeap(ro_space));
// The global shared ReadOnlyHeap is only used without pointer compression.
// The global shared ReadOnlyHeap is used with shared cage and if pointer
// compression is disabled.
SoleReadOnlyHeap::shared_ro_heap_ = sole_ro_heap.get();
ro_heap = std::move(sole_ro_heap);
}

View File

@ -87,7 +87,7 @@ class ReadOnlyHeap {
// Returns whether the ReadOnlySpace will actually be shared taking into
// account whether shared memory is available with pointer compression.
static bool IsReadOnlySpaceShared() {
static constexpr bool IsReadOnlySpaceShared() {
return V8_SHARED_RO_HEAP_BOOL &&
(!COMPRESS_POINTERS_BOOL || COMPRESS_POINTERS_IN_SHARED_CAGE_BOOL);
}
@ -96,6 +96,8 @@ class ReadOnlyHeap {
virtual void InitializeFromIsolateRoots(Isolate* isolate) {}
virtual bool IsOwnedByIsolate() { return true; }
bool init_complete() { return init_complete_; }
protected:
friend class ReadOnlyArtifacts;
friend class PointerCompressedReadOnlyArtifacts;

View File

@ -66,33 +66,93 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
return shared;
}
#ifdef DEBUG
bool IsMutableMap(InstanceType instance_type, ElementsKind elements_kind) {
bool is_js_object = InstanceTypeChecker::IsJSObject(instance_type);
bool is_wasm_object = false;
#if V8_ENABLE_WEBASSEMBLY
is_wasm_object =
instance_type == WASM_STRUCT_TYPE || instance_type == WASM_ARRAY_TYPE;
#endif // V8_ENABLE_WEBASSEMBLY
DCHECK_IMPLIES(is_js_object &&
!Map::CanHaveFastTransitionableElementsKind(instance_type),
IsDictionaryElementsKind(elements_kind) ||
IsTerminalElementsKind(elements_kind));
// JSObjects have maps with a mutable prototype_validity_cell, so they cannot
// go in RO_SPACE. Maps for managed Wasm objects have mutable subtype lists.
return is_js_object || is_wasm_object;
}
#endif
} // namespace
bool SetupIsolateDelegate::SetupHeapInternal(Isolate* isolate) {
return isolate->heap()->CreateHeapObjects();
auto heap = isolate->heap();
if (!isolate->read_only_heap()->init_complete()) {
if (!heap->CreateReadOnlyHeapObjects()) return false;
}
#ifdef DEBUG
auto ro_size = heap->read_only_space()->Size();
#endif
DCHECK_EQ(heap->old_space()->Size(), 0);
DCHECK_EQ(heap->new_space()->Size(), 0);
auto res = heap->CreateMutableHeapObjects();
DCHECK_EQ(heap->read_only_space()->Size(), ro_size);
return res;
}
bool Heap::CreateHeapObjects() {
bool Heap::CreateReadOnlyHeapObjects() {
// Create initial maps.
if (!CreateInitialMaps()) return false;
if (!CreateInitialReadOnlyMaps()) return false;
CreateReadOnlyApiObjects();
CreateInitialReadOnlyObjects();
#ifdef DEBUG
ReadOnlyRoots roots(isolate());
for (auto pos = RootIndex::kFirstReadOnlyRoot;
pos <= RootIndex::kLastReadOnlyRoot; ++pos) {
DCHECK(roots.at(pos));
}
#endif
return true;
}
bool Heap::CreateMutableHeapObjects() {
ReadOnlyRoots roots(this);
#define ALLOCATE_MAP(instance_type, size, field_name) \
{ \
Map map; \
if (!AllocateMap(AllocationType::kMap, (instance_type), size).To(&map)) \
return false; \
set_##field_name##_map(map); \
}
{ // Map allocation
ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kHeaderSize,
message_object)
ALLOCATE_MAP(JS_EXTERNAL_OBJECT_TYPE, JSExternalObject::kHeaderSize,
external)
external_map().set_is_extensible(false);
}
#undef ALLOCATE_MAP
// Ensure that all young generation pages are iterable. It must be after heap
// setup, so that the maps have been created.
if (new_space()) new_space()->MakeIterable();
CreateApiObjects();
CreateMutableApiObjects();
// Create initial objects
CreateInitialObjects();
CreateInitialMutableObjects();
CreateInternalAccessorInfoObjects();
CHECK_EQ(0u, gc_count_);
set_native_contexts_list(ReadOnlyRoots(this).undefined_value());
set_allocation_sites_list(ReadOnlyRoots(this).undefined_value());
set_dirty_js_finalization_registries_list(
ReadOnlyRoots(this).undefined_value());
set_dirty_js_finalization_registries_list_tail(
ReadOnlyRoots(this).undefined_value());
set_native_contexts_list(roots.undefined_value());
set_allocation_sites_list(roots.undefined_value());
set_dirty_js_finalization_registries_list(roots.undefined_value());
set_dirty_js_finalization_registries_list_tail(roots.undefined_value());
return true;
}
@ -129,28 +189,17 @@ const Heap::StructTable Heap::struct_table[] = {
#undef DATA_HANDLER_ELEMENT
};
AllocationResult Heap::AllocateMap(InstanceType instance_type,
AllocationResult Heap::AllocateMap(AllocationType allocation_type,
InstanceType instance_type,
int instance_size,
ElementsKind elements_kind,
int inobject_properties) {
static_assert(LAST_JS_OBJECT_TYPE == LAST_TYPE);
bool is_js_object = InstanceTypeChecker::IsJSObject(instance_type);
bool is_wasm_object = false;
#if V8_ENABLE_WEBASSEMBLY
is_wasm_object =
instance_type == WASM_STRUCT_TYPE || instance_type == WASM_ARRAY_TYPE;
#endif // V8_ENABLE_WEBASSEMBLY
DCHECK_IMPLIES(is_js_object &&
!Map::CanHaveFastTransitionableElementsKind(instance_type),
IsDictionaryElementsKind(elements_kind) ||
IsTerminalElementsKind(elements_kind));
HeapObject result;
// JSObjects have maps with a mutable prototype_validity_cell, so they cannot
// go in RO_SPACE. Maps for managed Wasm objects have mutable subtype lists.
bool is_mutable = is_js_object || is_wasm_object;
AllocationResult allocation =
AllocateRaw(Map::kSize, is_mutable ? AllocationType::kMap
: AllocationType::kReadOnly);
DCHECK_EQ(allocation_type, IsMutableMap(instance_type, elements_kind)
? AllocationType::kMap
: AllocationType::kReadOnly);
AllocationResult allocation = AllocateRaw(Map::kSize, allocation_type);
if (!allocation.To(&result)) return allocation;
result.set_map_after_allocation(ReadOnlyRoots(this).meta_map(),
@ -218,7 +267,8 @@ AllocationResult Heap::Allocate(Handle<Map> map,
return AllocationResult::FromObject(result);
}
bool Heap::CreateInitialMaps() {
bool Heap::CreateInitialReadOnlyMaps() {
ReadOnlyRoots roots(this);
HeapObject obj;
{
AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
@ -229,8 +279,6 @@ bool Heap::CreateInitialMaps() {
set_meta_map(new_meta_map);
new_meta_map.set_map_after_allocation(new_meta_map);
ReadOnlyRoots roots(this);
{ // Partial map allocation
#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \
{ \
Map map; \
@ -238,6 +286,7 @@ bool Heap::CreateInitialMaps() {
set_##field_name##_map(map); \
}
{ // Partial map allocation
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
ALLOCATE_PARTIAL_MAP(WEAK_FIXED_ARRAY_TYPE, kVariableSizeSentinel,
weak_fixed_array);
@ -360,12 +409,14 @@ bool Heap::CreateInitialMaps() {
FinalizePartialMap(Map::cast(Object(roots_table()[entry.index])));
}
{ // Map allocation
#define ALLOCATE_MAP(instance_type, size, field_name) \
{ \
Map map; \
if (!AllocateMap((instance_type), size).To(&map)) return false; \
set_##field_name##_map(map); \
#define ALLOCATE_MAP(instance_type, size, field_name) \
{ \
Map map; \
if (!AllocateMap(AllocationType::kReadOnly, (instance_type), size) \
.To(&map)) { \
return false; \
} \
set_##field_name##_map(map); \
}
#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
@ -379,6 +430,7 @@ bool Heap::CreateInitialMaps() {
(constructor_function_index)); \
}
{ // Map allocation
ALLOCATE_VARSIZE_MAP(SCOPE_INFO_TYPE, scope_info)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
ALLOCATE_VARSIZE_MAP(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE,
@ -406,7 +458,10 @@ bool Heap::CreateInitialMaps() {
for (unsigned i = 0; i < arraysize(string_type_table); i++) {
const StringTypeTable& entry = string_type_table[i];
Map map;
if (!AllocateMap(entry.type, entry.size).To(&map)) return false;
if (!AllocateMap(AllocationType::kReadOnly, entry.type, entry.size)
.To(&map)) {
return false;
}
map.SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
// Mark cons string maps as unstable, because their objects can change
// maps during GC.
@ -533,16 +588,11 @@ bool Heap::CreateInitialMaps() {
WasmContinuationObject::kSize, wasm_continuation_object)
ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kHeaderSize,
message_object)
ALLOCATE_MAP(JS_EXTERNAL_OBJECT_TYPE, JSExternalObject::kHeaderSize,
external)
external_map().set_is_extensible(false);
}
#undef ALLOCATE_PRIMITIVE_MAP
#undef ALLOCATE_VARSIZE_MAP
#undef ALLOCATE_MAP
}
{
AllocationResult alloc = AllocateRaw(
ArrayList::SizeFor(ArrayList::kFirstIndex), AllocationType::kReadOnly);
@ -656,20 +706,23 @@ bool Heap::CreateInitialMaps() {
return true;
}
void Heap::CreateApiObjects() {
void Heap::CreateMutableApiObjects() {
Isolate* isolate = this->isolate();
HandleScope scope(isolate);
set_message_listeners(*TemplateList::New(isolate, 2));
}
void Heap::CreateReadOnlyApiObjects() {
HandleScope scope(isolate());
Handle<InterceptorInfo> info =
Handle<InterceptorInfo>::cast(isolate->factory()->NewStruct(
Handle<InterceptorInfo>::cast(isolate()->factory()->NewStruct(
INTERCEPTOR_INFO_TYPE, AllocationType::kReadOnly));
info->set_flags(0);
set_noop_interceptor_info(*info);
}
void Heap::CreateInitialObjects() {
void Heap::CreateInitialReadOnlyObjects() {
HandleScope initial_objects_handle_scope(isolate());
Factory* factory = isolate()->factory();
ReadOnlyRoots roots(this);
@ -687,15 +740,18 @@ void Heap::CreateInitialObjects() {
*factory->NewHeapNumber<AllocationType::kReadOnly>(V8_INFINITY));
set_minus_infinity_value(
*factory->NewHeapNumber<AllocationType::kReadOnly>(-V8_INFINITY));
set_max_safe_integer(
*factory->NewHeapNumber<AllocationType::kReadOnly>(kMaxSafeInteger));
set_max_uint_32(
*factory->NewHeapNumber<AllocationType::kReadOnly>(kMaxUInt32));
set_smi_min_value(
*factory->NewHeapNumber<AllocationType::kReadOnly>(kSmiMinValue));
set_smi_max_value_plus_one(
*factory->NewHeapNumber<AllocationType::kReadOnly>(0.0 - kSmiMinValue));
set_hash_seed(*factory->NewByteArray(kInt64Size, AllocationType::kReadOnly));
InitializeHashSeed();
// There's no "current microtask" in the beginning.
set_current_microtask(roots.undefined_value());
set_weak_refs_keep_during_job(roots.undefined_value());
// Allocate and initialize table for single character one byte strings.
int table_size = String::kMaxOneByteCharCode + 1;
set_single_character_string_table(
@ -853,54 +909,13 @@ void Heap::CreateInitialObjects() {
Handle<RegisteredSymbolTable> empty_symbol_table = RegisteredSymbolTable::New(
isolate(), 1, AllocationType::kReadOnly, USE_CUSTOM_MINIMUM_CAPACITY);
DCHECK(!empty_symbol_table->HasSufficientCapacityToAdd(1));
set_public_symbol_table(*empty_symbol_table);
set_api_symbol_table(*empty_symbol_table);
set_api_private_symbol_table(*empty_symbol_table);
set_number_string_cache(*factory->NewFixedArray(
kInitialNumberStringCacheSize * 2, AllocationType::kOld));
set_basic_block_profiling_data(roots.empty_array_list());
// Allocate cache for string split and regexp-multiple.
set_string_split_cache(*factory->NewFixedArray(
RegExpResultsCache::kRegExpResultsCacheSize, AllocationType::kOld));
set_regexp_multiple_cache(*factory->NewFixedArray(
RegExpResultsCache::kRegExpResultsCacheSize, AllocationType::kOld));
// Allocate FeedbackCell for builtins.
Handle<FeedbackCell> many_closures_cell =
factory->NewManyClosuresCell(factory->undefined_value());
set_many_closures_cell(*many_closures_cell);
set_detached_contexts(roots.empty_weak_array_list());
set_retaining_path_targets(roots.empty_weak_array_list());
set_feedback_vectors_for_profiling_tools(roots.undefined_value());
set_functions_marked_for_manual_optimization(roots.undefined_value());
set_shared_wasm_memories(roots.empty_weak_array_list());
set_locals_block_list_cache(roots.undefined_value());
#ifdef V8_ENABLE_WEBASSEMBLY
set_active_continuation(roots.undefined_value());
set_active_suspender(roots.undefined_value());
set_js_to_wasm_wrappers(roots.empty_weak_array_list());
set_wasm_canonical_rtts(roots.empty_weak_array_list());
#endif // V8_ENABLE_WEBASSEMBLY
set_script_list(roots.empty_weak_array_list());
set_empty_symbol_table(*empty_symbol_table);
Handle<NumberDictionary> slow_element_dictionary = NumberDictionary::New(
isolate(), 1, AllocationType::kReadOnly, USE_CUSTOM_MINIMUM_CAPACITY);
DCHECK(!slow_element_dictionary->HasSufficientCapacityToAdd(1));
set_empty_slow_element_dictionary(*slow_element_dictionary);
set_materialized_objects(*factory->NewFixedArray(0, AllocationType::kOld));
// Handling of script id generation is in Heap::NextScriptId().
set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
set_last_debugging_id(Smi::FromInt(DebugInfo::kNoDebuggingId));
set_next_template_serial_number(Smi::zero());
// Allocate the empty OrderedHashMap.
Handle<OrderedHashMap> empty_ordered_hash_map =
OrderedHashMap::AllocateEmpty(isolate(), AllocationType::kReadOnly)
@ -942,6 +957,81 @@ void Heap::CreateInitialObjects() {
ScopeInfo::CreateForNativeContext(isolate());
set_native_scope_info(*native_scope_info);
// Canonical off-heap trampoline data
set_off_heap_trampoline_relocation_info(
*Builtins::GenerateOffHeapTrampolineRelocInfo(isolate_));
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// These roots will not be used.
HeapObject no_container = *isolate()->factory()->undefined_value();
set_trampoline_trivial_code_data_container(no_container);
set_trampoline_promise_rejection_code_data_container(no_container);
} else {
set_trampoline_trivial_code_data_container(
*isolate()->factory()->NewCodeDataContainer(0,
AllocationType::kReadOnly));
set_trampoline_promise_rejection_code_data_container(
*isolate()->factory()->NewCodeDataContainer(
Code::IsPromiseRejectionField::encode(true),
AllocationType::kReadOnly));
}
}
void Heap::CreateInitialMutableObjects() {
HandleScope initial_objects_handle_scope(isolate());
Factory* factory = isolate()->factory();
ReadOnlyRoots roots(this);
// There's no "current microtask" in the beginning.
set_current_microtask(roots.undefined_value());
set_weak_refs_keep_during_job(roots.undefined_value());
set_public_symbol_table(roots.empty_symbol_table());
set_api_symbol_table(roots.empty_symbol_table());
set_api_private_symbol_table(roots.empty_symbol_table());
set_number_string_cache(*factory->NewFixedArray(
kInitialNumberStringCacheSize * 2, AllocationType::kOld));
set_basic_block_profiling_data(roots.empty_array_list());
// Allocate cache for string split and regexp-multiple.
set_string_split_cache(*factory->NewFixedArray(
RegExpResultsCache::kRegExpResultsCacheSize, AllocationType::kOld));
set_regexp_multiple_cache(*factory->NewFixedArray(
RegExpResultsCache::kRegExpResultsCacheSize, AllocationType::kOld));
// Allocate FeedbackCell for builtins.
Handle<FeedbackCell> many_closures_cell =
factory->NewManyClosuresCell(factory->undefined_value());
set_many_closures_cell(*many_closures_cell);
set_detached_contexts(roots.empty_weak_array_list());
set_retaining_path_targets(roots.empty_weak_array_list());
set_feedback_vectors_for_profiling_tools(roots.undefined_value());
set_functions_marked_for_manual_optimization(roots.undefined_value());
set_shared_wasm_memories(roots.empty_weak_array_list());
set_locals_block_list_cache(roots.undefined_value());
#ifdef V8_ENABLE_WEBASSEMBLY
set_active_continuation(roots.undefined_value());
set_active_suspender(roots.undefined_value());
set_js_to_wasm_wrappers(roots.empty_weak_array_list());
set_wasm_canonical_rtts(roots.empty_weak_array_list());
#endif // V8_ENABLE_WEBASSEMBLY
set_script_list(roots.empty_weak_array_list());
set_materialized_objects(*factory->NewFixedArray(0, AllocationType::kOld));
// Handling of script id generation is in Heap::NextScriptId().
set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
set_last_debugging_id(Smi::FromInt(DebugInfo::kNoDebuggingId));
set_next_template_serial_number(Smi::zero());
// Allocate the empty script.
Handle<Script> script = factory->NewScript(factory->empty_string());
script->set_type(Script::TYPE_NATIVE);
@ -972,27 +1062,6 @@ void Heap::CreateInitialObjects() {
set_serialized_objects(roots.empty_fixed_array());
set_serialized_global_proxy_sizes(roots.empty_fixed_array());
/* Canonical off-heap trampoline data */
set_off_heap_trampoline_relocation_info(
*Builtins::GenerateOffHeapTrampolineRelocInfo(isolate_));
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// These roots will not be used.
HeapObject no_container = *isolate()->factory()->undefined_value();
set_trampoline_trivial_code_data_container(no_container);
set_trampoline_promise_rejection_code_data_container(no_container);
} else {
set_trampoline_trivial_code_data_container(
*isolate()->factory()->NewCodeDataContainer(0,
AllocationType::kReadOnly));
set_trampoline_promise_rejection_code_data_container(
*isolate()->factory()->NewCodeDataContainer(
Code::IsPromiseRejectionField::encode(true),
AllocationType::kReadOnly));
}
// Evaluate the hash values which will then be cached in the strings.
isolate()->factory()->zero_string()->EnsureHash();
isolate()->factory()->one_string()->EnsureHash();

View File

@ -56,5 +56,17 @@ READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK)
#undef ROOT_TYPE_CHECK
#endif
Handle<HeapNumber> ReadOnlyRoots::FindHeapNumber(double value) {
auto bits = base::bit_cast<uint64_t>(value);
for (auto pos = RootIndex::kFirstHeapNumberRoot;
pos <= RootIndex::kLastHeapNumberRoot; ++pos) {
auto root = HeapNumber::cast(Object(at(pos)));
if (base::bit_cast<uint64_t>(root.value()) == bits) {
return Handle<HeapNumber>(GetLocation(pos));
}
}
return Handle<HeapNumber>();
}
} // namespace internal
} // namespace v8

View File

@ -34,6 +34,18 @@ class RootVisitor;
class String;
class Symbol;
#define STRONG_READ_ONLY_HEAP_NUMBER_ROOT_LIST(V) \
/* Special numbers */ \
V(HeapNumber, nan_value, NanValue) \
V(HeapNumber, hole_nan_value, HoleNanValue) \
V(HeapNumber, infinity_value, InfinityValue) \
V(HeapNumber, minus_zero_value, MinusZeroValue) \
V(HeapNumber, minus_infinity_value, MinusInfinityValue) \
V(HeapNumber, max_safe_integer, MaxSafeInteger) \
V(HeapNumber, max_uint_32, MaxUInt32) \
V(HeapNumber, smi_min_value, SmiMinValue) \
V(HeapNumber, smi_max_value_plus_one, SmiMaxValuePlusOne)
// Defines all the read-only roots in Heap.
#define STRONG_READ_ONLY_ROOT_LIST(V) \
/* Cluster the most popular ones in a few cache lines here at the top. */ \
@ -199,12 +211,7 @@ class Symbol;
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \
/* Special numbers */ \
V(HeapNumber, nan_value, NanValue) \
V(HeapNumber, hole_nan_value, HoleNanValue) \
V(HeapNumber, infinity_value, InfinityValue) \
V(HeapNumber, minus_zero_value, MinusZeroValue) \
V(HeapNumber, minus_infinity_value, MinusInfinityValue) \
STRONG_READ_ONLY_HEAP_NUMBER_ROOT_LIST(V) \
/* Table of strings of one-byte single characters */ \
V(FixedArray, single_character_string_table, SingleCharacterStringTable) \
/* Marker for self-references during code-generation */ \
@ -222,6 +229,7 @@ class Symbol;
V(ScopeInfo, global_this_binding_scope_info, GlobalThisBindingScopeInfo) \
V(ScopeInfo, empty_function_scope_info, EmptyFunctionScopeInfo) \
V(ScopeInfo, native_scope_info, NativeScopeInfo) \
V(RegisteredSymbolTable, empty_symbol_table, EmptySymbolTable) \
/* Hash seed */ \
V(ByteArray, hash_seed, HashSeed)
@ -431,6 +439,9 @@ enum class RootIndex : uint16_t {
kFirstReadOnlyRoot = kFirstRoot,
kLastReadOnlyRoot = kFirstReadOnlyRoot + kReadOnlyRootsCount - 1,
kFirstHeapNumberRoot = kNanValue,
kLastHeapNumberRoot = kSmiMaxValuePlusOne,
// Use for fast protector update checks
kFirstNameForProtector = kconstructor_string,
kNameForProtectorCount = 0 NAME_FOR_PROTECTOR_ROOT_LIST(COUNT_ROOT),
@ -516,6 +527,12 @@ class RootsTable {
static_cast<unsigned>(RootIndex::kLastImmortalImmovableRoot);
}
static constexpr bool IsReadOnly(RootIndex root_index) {
static_assert(static_cast<int>(RootIndex::kFirstReadOnlyRoot) == 0);
return static_cast<unsigned>(root_index) <=
static_cast<unsigned>(RootIndex::kLastReadOnlyRoot);
}
private:
FullObjectSlot begin() {
return FullObjectSlot(&roots_[static_cast<size_t>(RootIndex::kFirstRoot)]);
@ -614,6 +631,10 @@ class ReadOnlyRoots {
void VerifyNameForProtectors();
#endif
// Returns heap number with identical value if it already exists or the empty
// handle otherwise.
Handle<HeapNumber> FindHeapNumber(double value);
// Get the address of a given read-only root index, without type checks.
V8_INLINE Address at(RootIndex root_index) const;

View File

@ -125,6 +125,17 @@ class TestSerializer {
return v8_isolate;
}
static v8::Isolate* NewIsolateFromReadOnlySnapshot(
SnapshotData* read_only_snapshot) {
const bool kEnableSerializer = false;
const bool kIsShared = false;
v8::Isolate* v8_isolate = NewIsolate(kEnableSerializer, kIsShared);
v8::Isolate::Scope isolate_scope(v8_isolate);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->InitWithReadOnlySnapshot(read_only_snapshot);
return v8_isolate;
}
static void InitializeProcessWideSharedIsolateFromBlob(
const StartupBlobs& blobs) {
base::MutexGuard guard(
@ -5296,5 +5307,52 @@ UNINITIALIZED_TEST(BreakPointAccessorContextSnapshot) {
FreeCurrentEmbeddedBlob();
}
#if V8_EXTERNAL_CODE_SPACE_BOOL
UNINITIALIZED_TEST(CreateIsolateFromReadOnlySnapshot) {
auto working_builtins = [](v8::Isolate* isolate) {
v8::Isolate::Scope i_scope(isolate);
v8::HandleScope h_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope c_scope(context);
v8::Maybe<int32_t> result = CompileRun("(function(x){return +x+40})(\"2\")")
->Int32Value(isolate->GetCurrentContext());
CHECK_EQ(42, result.FromJust());
};
v8::Isolate* isolate1 = TestSerializer::NewIsolateInitialized();
StartupBlobs blobs1 = Serialize(isolate1);
auto ro1 = SnapshotData(blobs1.read_only);
isolate1->Dispose();
v8::Isolate* isolate2 = TestSerializer::NewIsolateFromReadOnlySnapshot(&ro1);
auto blobs2 = Serialize(isolate2);
auto ro2 = SnapshotData(blobs2.read_only);
isolate2->Dispose();
v8::Isolate* isolate3 = TestSerializer::NewIsolateFromReadOnlySnapshot(&ro2);
auto blobs3 = Serialize(isolate3);
auto ro3 = SnapshotData(blobs3.read_only);
isolate3->Dispose();
v8::Isolate* isolate4 = TestSerializer::NewIsolateFromBlob(blobs2);
working_builtins(isolate4);
isolate4->Dispose();
v8::Isolate* isolate5 = TestSerializer::NewIsolateFromBlob(blobs3);
working_builtins(isolate5);
isolate5->Dispose();
// The first snapshot is not stable since the serializer does not preserve the
// order of objects in the read only heap.
CHECK_EQ(blobs2.startup, blobs3.startup);
CHECK_EQ(blobs2.shared_space, blobs3.shared_space);
CHECK_EQ(blobs2.read_only, blobs3.read_only);
blobs1.Dispose();
blobs2.Dispose();
blobs3.Dispose();
FreeCurrentEmbeddedBlob();
}
#endif // V8_EXTERNAL_CODE_SPACE_BOOL
} // namespace internal
} // namespace v8

View File

@ -93,6 +93,17 @@ TEST_F(RootsTest, TestHeapRootsNotReadOnly) {
MUTABLE_ROOT_LIST(CHECK_NOT_IN_RO_SPACE)
}
TEST_F(RootsTest, TestHeapNumberList) {
ReadOnlyRoots roots(isolate());
for (auto pos = RootIndex::kFirstReadOnlyRoot;
pos <= RootIndex::kLastReadOnlyRoot; ++pos) {
auto obj = Object(roots.at(pos));
bool in_nr_range = pos >= RootIndex::kFirstHeapNumberRoot &&
pos <= RootIndex::kLastHeapNumberRoot;
CHECK_EQ(obj.IsHeapNumber(), in_nr_range);
}
}
#undef CHECK_NOT_IN_RO_SPACE
} // namespace internal

View File

@ -4,7 +4,7 @@ tools/gcmole/gcmole-test.cc:30:10: warning: Possibly stale variable due to GCs.
tools/gcmole/gcmole-test.cc:28:20: note: Call might cause unexpected GC.
isolate->heap()->CollectGarbage(OLD_SPACE, GarbageCollectionReason::kTesting);
^
./src/heap/heap.h:981:21: note: GC call here.
./src/heap/heap.h:983:21: note: GC call here.
V8_EXPORT_PRIVATE bool CollectGarbage(
^
tools/gcmole/gcmole-test.cc:48:3: warning: Possible problem with evaluation order with interleaved GCs.

View File

@ -394,75 +394,75 @@ KNOWN_MAPS = {
("read_only_space", 0x03499): (131, "BasicBlockCountersMarkerMap"),
("read_only_space", 0x034dd): (146, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x035dd): (158, "InterceptorInfoMap"),
("read_only_space", 0x075f1): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x07619): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x07641): (134, "CallableTaskMap"),
("read_only_space", 0x07669): (135, "CallbackTaskMap"),
("read_only_space", 0x07691): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x076b9): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x076e1): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x07709): (141, "AccessCheckInfoMap"),
("read_only_space", 0x07731): (142, "AccessorPairMap"),
("read_only_space", 0x07759): (143, "AliasedArgumentsEntryMap"),
("read_only_space", 0x07781): (144, "AllocationMementoMap"),
("read_only_space", 0x077a9): (147, "AsmWasmDataMap"),
("read_only_space", 0x077d1): (148, "AsyncGeneratorRequestMap"),
("read_only_space", 0x077f9): (149, "BreakPointMap"),
("read_only_space", 0x07821): (150, "BreakPointInfoMap"),
("read_only_space", 0x07849): (151, "CallSiteInfoMap"),
("read_only_space", 0x07871): (152, "ClassPositionsMap"),
("read_only_space", 0x07899): (153, "DebugInfoMap"),
("read_only_space", 0x078c1): (155, "ErrorStackDataMap"),
("read_only_space", 0x078e9): (157, "FunctionTemplateRareDataMap"),
("read_only_space", 0x07911): (159, "InterpreterDataMap"),
("read_only_space", 0x07939): (160, "ModuleRequestMap"),
("read_only_space", 0x07961): (161, "PromiseCapabilityMap"),
("read_only_space", 0x07989): (162, "PromiseOnStackMap"),
("read_only_space", 0x079b1): (163, "PromiseReactionMap"),
("read_only_space", 0x079d9): (164, "PropertyDescriptorObjectMap"),
("read_only_space", 0x07a01): (165, "PrototypeInfoMap"),
("read_only_space", 0x07a29): (166, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x07a51): (167, "ScriptMap"),
("read_only_space", 0x07a79): (168, "ScriptOrModuleMap"),
("read_only_space", 0x07aa1): (169, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x07ac9): (170, "StackFrameInfoMap"),
("read_only_space", 0x07af1): (171, "TemplateObjectDescriptionMap"),
("read_only_space", 0x07b19): (172, "Tuple2Map"),
("read_only_space", 0x07b41): (173, "WasmExceptionTagMap"),
("read_only_space", 0x07b69): (174, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x07b91): (194, "SloppyArgumentsElementsMap"),
("read_only_space", 0x07bb9): (227, "DescriptorArrayMap"),
("read_only_space", 0x07be1): (202, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x07c09): (200, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x07c31): (203, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x07c59): (201, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x07c81): (248, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x07ca9): (195, "TurbofanBitsetTypeMap"),
("read_only_space", 0x07cd1): (199, "TurbofanUnionTypeMap"),
("read_only_space", 0x07cf9): (198, "TurbofanRangeTypeMap"),
("read_only_space", 0x07d21): (196, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x07d49): (197, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x07d71): (244, "InternalClassMap"),
("read_only_space", 0x07d99): (255, "SmiPairMap"),
("read_only_space", 0x07dc1): (254, "SmiBoxMap"),
("read_only_space", 0x07de9): (219, "ExportedSubClassBaseMap"),
("read_only_space", 0x07e11): (220, "ExportedSubClassMap"),
("read_only_space", 0x07e39): (225, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x07e61): (226, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x07e89): (193, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x07eb1): (245, "InternalClassWithStructElementsMap"),
("read_only_space", 0x07ed9): (221, "ExportedSubClass2Map"),
("read_only_space", 0x07f01): (256, "SortStateMap"),
("read_only_space", 0x07f29): (262, "WasmStringViewIterMap"),
("read_only_space", 0x07f51): (145, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x07f79): (145, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x08045): (137, "LoadHandler1Map"),
("read_only_space", 0x0806d): (137, "LoadHandler2Map"),
("read_only_space", 0x08095): (137, "LoadHandler3Map"),
("read_only_space", 0x080bd): (138, "StoreHandler0Map"),
("read_only_space", 0x080e5): (138, "StoreHandler1Map"),
("read_only_space", 0x0810d): (138, "StoreHandler2Map"),
("read_only_space", 0x08135): (138, "StoreHandler3Map"),
("read_only_space", 0x0763d): (132, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x07665): (133, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x0768d): (134, "CallableTaskMap"),
("read_only_space", 0x076b5): (135, "CallbackTaskMap"),
("read_only_space", 0x076dd): (136, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x07705): (139, "FunctionTemplateInfoMap"),
("read_only_space", 0x0772d): (140, "ObjectTemplateInfoMap"),
("read_only_space", 0x07755): (141, "AccessCheckInfoMap"),
("read_only_space", 0x0777d): (142, "AccessorPairMap"),
("read_only_space", 0x077a5): (143, "AliasedArgumentsEntryMap"),
("read_only_space", 0x077cd): (144, "AllocationMementoMap"),
("read_only_space", 0x077f5): (147, "AsmWasmDataMap"),
("read_only_space", 0x0781d): (148, "AsyncGeneratorRequestMap"),
("read_only_space", 0x07845): (149, "BreakPointMap"),
("read_only_space", 0x0786d): (150, "BreakPointInfoMap"),
("read_only_space", 0x07895): (151, "CallSiteInfoMap"),
("read_only_space", 0x078bd): (152, "ClassPositionsMap"),
("read_only_space", 0x078e5): (153, "DebugInfoMap"),
("read_only_space", 0x0790d): (155, "ErrorStackDataMap"),
("read_only_space", 0x07935): (157, "FunctionTemplateRareDataMap"),
("read_only_space", 0x0795d): (159, "InterpreterDataMap"),
("read_only_space", 0x07985): (160, "ModuleRequestMap"),
("read_only_space", 0x079ad): (161, "PromiseCapabilityMap"),
("read_only_space", 0x079d5): (162, "PromiseOnStackMap"),
("read_only_space", 0x079fd): (163, "PromiseReactionMap"),
("read_only_space", 0x07a25): (164, "PropertyDescriptorObjectMap"),
("read_only_space", 0x07a4d): (165, "PrototypeInfoMap"),
("read_only_space", 0x07a75): (166, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x07a9d): (167, "ScriptMap"),
("read_only_space", 0x07ac5): (168, "ScriptOrModuleMap"),
("read_only_space", 0x07aed): (169, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x07b15): (170, "StackFrameInfoMap"),
("read_only_space", 0x07b3d): (171, "TemplateObjectDescriptionMap"),
("read_only_space", 0x07b65): (172, "Tuple2Map"),
("read_only_space", 0x07b8d): (173, "WasmExceptionTagMap"),
("read_only_space", 0x07bb5): (174, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x07bdd): (194, "SloppyArgumentsElementsMap"),
("read_only_space", 0x07c05): (227, "DescriptorArrayMap"),
("read_only_space", 0x07c2d): (202, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x07c55): (200, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x07c7d): (203, "UncompiledDataWithoutPreparseDataWithJobMap"),
("read_only_space", 0x07ca5): (201, "UncompiledDataWithPreparseDataAndJobMap"),
("read_only_space", 0x07ccd): (248, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x07cf5): (195, "TurbofanBitsetTypeMap"),
("read_only_space", 0x07d1d): (199, "TurbofanUnionTypeMap"),
("read_only_space", 0x07d45): (198, "TurbofanRangeTypeMap"),
("read_only_space", 0x07d6d): (196, "TurbofanHeapConstantTypeMap"),
("read_only_space", 0x07d95): (197, "TurbofanOtherNumberConstantTypeMap"),
("read_only_space", 0x07dbd): (244, "InternalClassMap"),
("read_only_space", 0x07de5): (255, "SmiPairMap"),
("read_only_space", 0x07e0d): (254, "SmiBoxMap"),
("read_only_space", 0x07e35): (219, "ExportedSubClassBaseMap"),
("read_only_space", 0x07e5d): (220, "ExportedSubClassMap"),
("read_only_space", 0x07e85): (225, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x07ead): (226, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x07ed5): (193, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x07efd): (245, "InternalClassWithStructElementsMap"),
("read_only_space", 0x07f25): (221, "ExportedSubClass2Map"),
("read_only_space", 0x07f4d): (256, "SortStateMap"),
("read_only_space", 0x07f75): (262, "WasmStringViewIterMap"),
("read_only_space", 0x07f9d): (145, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x07fc5): (145, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x08091): (137, "LoadHandler1Map"),
("read_only_space", 0x080b9): (137, "LoadHandler2Map"),
("read_only_space", 0x080e1): (137, "LoadHandler3Map"),
("read_only_space", 0x08109): (138, "StoreHandler0Map"),
("read_only_space", 0x08131): (138, "StoreHandler1Map"),
("read_only_space", 0x08159): (138, "StoreHandler2Map"),
("read_only_space", 0x08181): (138, "StoreHandler3Map"),
("old_space", 0x0438d): (2116, "ExternalMap"),
("old_space", 0x043b5): (2120, "JSMessageObjectMap"),
}
@ -507,14 +507,19 @@ KNOWN_OBJECTS = {
("read_only_space", 0x03649): "InfinityValue",
("read_only_space", 0x03655): "MinusZeroValue",
("read_only_space", 0x03661): "MinusInfinityValue",
("read_only_space", 0x0366d): "SingleCharacterStringTable",
("read_only_space", 0x04a75): "SelfReferenceMarker",
("read_only_space", 0x04ab5): "BasicBlockCountersMarker",
("read_only_space", 0x04af9): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x04b05): "GlobalThisBindingScopeInfo",
("read_only_space", 0x04b35): "EmptyFunctionScopeInfo",
("read_only_space", 0x04b59): "NativeScopeInfo",
("read_only_space", 0x04b71): "HashSeed",
("read_only_space", 0x0366d): "MaxSafeInteger",
("read_only_space", 0x03679): "MaxUInt32",
("read_only_space", 0x03685): "SmiMinValue",
("read_only_space", 0x03691): "SmiMaxValuePlusOne",
("read_only_space", 0x0369d): "SingleCharacterStringTable",
("read_only_space", 0x04aa5): "SelfReferenceMarker",
("read_only_space", 0x04ae5): "BasicBlockCountersMarker",
("read_only_space", 0x04b29): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x04b35): "GlobalThisBindingScopeInfo",
("read_only_space", 0x04b65): "EmptyFunctionScopeInfo",
("read_only_space", 0x04b89): "NativeScopeInfo",
("read_only_space", 0x04ba1): "EmptySymbolTable",
("read_only_space", 0x04bbd): "HashSeed",
("old_space", 0x0423d): "ArgumentsIteratorAccessor",
("old_space", 0x04255): "ArrayLengthAccessor",
("old_space", 0x0426d): "BoundFunctionLengthAccessor",
@ -553,30 +558,30 @@ KNOWN_OBJECTS = {
("old_space", 0x04581): "StringSplitCache",
("old_space", 0x04989): "RegExpMultipleCache",
("old_space", 0x04d91): "BuiltinsConstantsTable",
("old_space", 0x051f9): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x0521d): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x05241): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x05265): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05289): "AsyncGeneratorYieldWithAwaitResolveSharedFun",
("old_space", 0x052ad): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x052d1): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x052f5): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x05319): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x0533d): "PromiseAllResolveElementSharedFun",
("old_space", 0x05361): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05385): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x053a9): "PromiseAnyRejectElementSharedFun",
("old_space", 0x053cd): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x053f1): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x05415): "PromiseCatchFinallySharedFun",
("old_space", 0x05439): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x0545d): "PromiseThenFinallySharedFun",
("old_space", 0x05481): "PromiseThrowerFinallySharedFun",
("old_space", 0x054a5): "PromiseValueThunkFinallySharedFun",
("old_space", 0x054c9): "ProxyRevokeSharedFun",
("old_space", 0x054ed): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x05511): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x05535): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
("old_space", 0x051b9): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x051dd): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x05201): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x05225): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05249): "AsyncGeneratorYieldWithAwaitResolveSharedFun",
("old_space", 0x0526d): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x05291): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x052b5): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x052d9): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x052fd): "PromiseAllResolveElementSharedFun",
("old_space", 0x05321): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05345): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x05369): "PromiseAnyRejectElementSharedFun",
("old_space", 0x0538d): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x053b1): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x053d5): "PromiseCatchFinallySharedFun",
("old_space", 0x053f9): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x0541d): "PromiseThenFinallySharedFun",
("old_space", 0x05441): "PromiseThrowerFinallySharedFun",
("old_space", 0x05465): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05489): "ProxyRevokeSharedFun",
("old_space", 0x054ad): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x054d1): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x054f5): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.