[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:
parent
710f2a4da2
commit
331c577e1d
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user