Commit 2f8a7561 authored by Frank Emrich's avatar Frank Emrich Committed by Commit Bot

[dict-proto] C++ implementation of SwissNameDictionary, pt. 3

This CL is part of a series that adds the C++ implementation of
SwissNameDictionary, a deterministic property backing store based on
Swiss Tables.

This CL adds the initialization code, factory functions and a
canonical SwissNameDictionary plus all helpers required for that.

Bug: v8:11388
Change-Id: I6bb92740afefc7d05433cfa62023e6da5e8213c7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2688058Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Frank Emrich <emrich@google.com>
Cr-Commit-Position: refs/heads/master@{#72824}
parent c7bad606
......@@ -22,6 +22,7 @@
#include "src/objects/source-text-module.h"
#include "src/objects/string-inl.h"
#include "src/objects/string.h"
#include "src/objects/swiss-name-dictionary-inl.h"
#include "src/objects/template-objects-inl.h"
namespace v8 {
......@@ -848,6 +849,43 @@ HeapObject FactoryBase<Impl>::AllocateRaw(int size, AllocationType allocation,
return impl()->AllocateRaw(size, allocation, alignment);
}
template <typename Impl>
Handle<SwissNameDictionary>
FactoryBase<Impl>::NewSwissNameDictionaryWithCapacity(
int capacity, AllocationType allocation) {
DCHECK(SwissNameDictionary::IsValidCapacity(capacity));
if (capacity == 0) {
DCHECK_NE(read_only_roots().at(RootIndex::kEmptySwissPropertyDictionary),
kNullAddress);
return read_only_roots().empty_swiss_property_dictionary_handle();
}
if (capacity > SwissNameDictionary::MaxCapacity()) {
isolate()->FatalProcessOutOfHeapMemory("invalid table size");
}
int meta_table_length = SwissNameDictionary::MetaTableSizeFor(capacity);
Handle<ByteArray> meta_table =
impl()->NewByteArray(meta_table_length, allocation);
Map map = read_only_roots().swiss_name_dictionary_map();
int size = SwissNameDictionary::SizeFor(capacity);
HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
Handle<SwissNameDictionary> table(SwissNameDictionary::cast(result),
isolate());
table->Initialize(isolate(), *meta_table, capacity);
return table;
}
template <typename Impl>
Handle<SwissNameDictionary> FactoryBase<Impl>::NewSwissNameDictionary(
int at_least_space_for, AllocationType allocation) {
return NewSwissNameDictionaryWithCapacity(
SwissNameDictionary::CapacityFor(at_least_space_for), allocation);
}
// Instantiate FactoryBase for the two variants we want.
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) FactoryBase<Factory>;
template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
......
......@@ -221,6 +221,13 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
Handle<ClassPositions> NewClassPositions(int start, int end);
Handle<SwissNameDictionary> NewSwissNameDictionary(
int at_least_space_for = kSwissNameDictionaryInitialCapacity,
AllocationType allocation = AllocationType::kYoung);
Handle<SwissNameDictionary> NewSwissNameDictionaryWithCapacity(
int capacity, AllocationType allocation);
protected:
// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
HeapObject AllocateRawArray(int size, AllocationType allocation);
......
......@@ -553,6 +553,27 @@ Handle<PropertyDescriptorObject> Factory::NewPropertyDescriptorObject() {
return object;
}
Handle<SwissNameDictionary> Factory::CreateCanonicalEmptySwissNameDictionary() {
// This function is only supposed to be used to create the canonical empty
// version and should not be used afterwards.
DCHECK_EQ(kNullAddress, ReadOnlyRoots(isolate()).at(
RootIndex::kEmptySwissPropertyDictionary));
ReadOnlyRoots roots(isolate());
Handle<ByteArray> empty_meta_table =
NewByteArray(SwissNameDictionary::kMetaTableEnumerationTableStartOffset,
AllocationType::kReadOnly);
Map map = roots.swiss_name_dictionary_map();
int size = SwissNameDictionary::SizeFor(0);
HeapObject obj =
AllocateRawWithImmortalMap(size, AllocationType::kReadOnly, map);
SwissNameDictionary result = SwissNameDictionary::cast(obj);
result.Initialize(isolate(), *empty_meta_table, 0);
return handle(result, isolate());
}
// Internalized strings are created in the old generation (data space).
Handle<String> Factory::InternalizeUtf8String(
const Vector<const char>& string) {
......
......@@ -171,6 +171,8 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
int capacity = kSmallOrderedHashMapMinCapacity,
AllocationType allocation = AllocationType::kYoung);
Handle<SwissNameDictionary> CreateCanonicalEmptySwissNameDictionary();
// Create a new PrototypeInfo struct.
Handle<PrototypeInfo> NewPrototypeInfo();
......
......@@ -819,6 +819,11 @@ void Heap::CreateInitialObjects() {
.ToHandleChecked();
set_empty_ordered_property_dictionary(*empty_ordered_property_dictionary);
// Allocate the empty SwissNameDictionary
Handle<SwissNameDictionary> empty_swiss_property_dictionary =
factory->CreateCanonicalEmptySwissNameDictionary();
set_empty_swiss_property_dictionary(*empty_swiss_property_dictionary);
// Allocate the empty FeedbackMetadata.
Handle<FeedbackMetadata> empty_feedback_metadata =
factory->NewFeedbackMetadata(0, 0, AllocationType::kReadOnly);
......
......@@ -5,6 +5,8 @@
#ifndef V8_OBJECTS_SWISS_NAME_DICTIONARY_INL_H_
#define V8_OBJECTS_SWISS_NAME_DICTIONARY_INL_H_
#include <algorithm>
#include "src/base/macros.h"
#include "src/execution/isolate-utils-inl.h"
#include "src/heap/heap.h"
......@@ -26,10 +28,41 @@ namespace internal {
CAST_ACCESSOR(SwissNameDictionary)
OBJECT_CONSTRUCTORS_IMPL(SwissNameDictionary, HeapObject)
const swiss_table::ctrl_t* SwissNameDictionary::CtrlTable() {
return reinterpret_cast<ctrl_t*>(
field_address(CtrlTableStartOffset(Capacity())));
}
int SwissNameDictionary::Capacity() {
return ReadField<int32_t>(CapacityOffset());
}
void SwissNameDictionary::SetCapacity(int capacity) {
DCHECK(IsValidCapacity(capacity));
WriteField(CapacityOffset(), capacity);
}
int SwissNameDictionary::NumberOfElements() {
return GetMetaTableField(kMetaTableElementCountOffset);
}
int SwissNameDictionary::NumberOfDeletedElements() {
return GetMetaTableField(kMetaTableDeletedElementCountOffset);
}
void SwissNameDictionary::SetNumberOfElements(int elements) {
SetMetaTableField(kMetaTableElementCountOffset, elements);
}
void SwissNameDictionary::SetNumberOfDeletedElements(int deleted_elements) {
SetMetaTableField(kMetaTableDeletedElementCountOffset, deleted_elements);
}
int SwissNameDictionary::UsedCapacity() {
return NumberOfElements() + NumberOfDeletedElements();
}
// static
constexpr bool SwissNameDictionary::IsValidCapacity(int capacity) {
return capacity == 0 || (capacity >= kInitialCapacity &&
......@@ -55,6 +88,180 @@ constexpr int SwissNameDictionary::SizeFor(int capacity) {
return PropertyDetailsTableStartOffset(capacity) + capacity;
}
// We use 7/8th as maximum load factor for non-special cases.
// For 16-wide groups, that gives an average of two empty slots per group.
// Similar to Abseil's CapacityToGrowth.
// static
constexpr int SwissNameDictionary::MaxUsableCapacity(int capacity) {
CONSTEXPR_DCHECK(IsValidCapacity(capacity));
if (Group::kWidth == 8 && capacity == 4) {
// If the group size is 16 we can fully utilize capacity 4: There will be
// enough kEmpty entries in the ctrl table.
return 3;
}
return capacity - capacity / 8;
}
// Returns |at_least_space_for| * 8/7 for non-special cases. Similar to Abseil's
// GrowthToLowerboundCapacity.
// static
int SwissNameDictionary::CapacityFor(int at_least_space_for) {
if (at_least_space_for <= 4) {
if (at_least_space_for == 0) {
return 0;
} else if (at_least_space_for < 4) {
return 4;
} else if (kGroupWidth == 16) {
DCHECK_EQ(4, at_least_space_for);
return 4;
} else if (kGroupWidth == 8) {
DCHECK_EQ(4, at_least_space_for);
return 8;
}
}
int non_normalized = at_least_space_for + at_least_space_for / 7;
return base::bits::RoundUpToPowerOfTwo32(non_normalized);
}
void SwissNameDictionary::SetMetaTableField(int field_index, int value) {
// See the STATIC_ASSERTs on |kMax1ByteMetaTableCapacity| and
// |kMax2ByteMetaTableCapacity| in the .cc file for an explanation of these
// constants.
int capacity = Capacity();
ByteArray meta_table = this->meta_table();
if (capacity <= kMax1ByteMetaTableCapacity) {
SetMetaTableField<uint8_t>(meta_table, field_index, value);
} else if (capacity <= kMax2ByteMetaTableCapacity) {
SetMetaTableField<uint16_t>(meta_table, field_index, value);
} else {
SetMetaTableField<uint32_t>(meta_table, field_index, value);
}
}
int SwissNameDictionary::GetMetaTableField(int field_index) {
// See the STATIC_ASSERTs on |kMax1ByteMetaTableCapacity| and
// |kMax2ByteMetaTableCapacity| in the .cc file for an explanation of these
// constants.
int capacity = Capacity();
ByteArray meta_table = this->meta_table();
if (capacity <= kMax1ByteMetaTableCapacity) {
return GetMetaTableField<uint8_t>(meta_table, field_index);
} else if (capacity <= kMax2ByteMetaTableCapacity) {
return GetMetaTableField<uint16_t>(meta_table, field_index);
} else {
return GetMetaTableField<uint32_t>(meta_table, field_index);
}
}
// static
template <typename T>
void SwissNameDictionary::SetMetaTableField(ByteArray meta_table,
int field_index, int value) {
STATIC_ASSERT((std::is_same<T, uint8_t>::value) ||
(std::is_same<T, uint16_t>::value) ||
(std::is_same<T, uint32_t>::value));
DCHECK_LE(value, std::numeric_limits<T>::max());
DCHECK_LT(meta_table.GetDataStartAddress() + field_index * sizeof(T),
meta_table.GetDataEndAddress());
T* raw_data = reinterpret_cast<T*>(meta_table.GetDataStartAddress());
raw_data[field_index] = value;
}
// static
template <typename T>
int SwissNameDictionary::GetMetaTableField(ByteArray meta_table,
int field_index) {
STATIC_ASSERT((std::is_same<T, uint8_t>::value) ||
(std::is_same<T, uint16_t>::value) ||
(std::is_same<T, uint32_t>::value));
DCHECK_LT(meta_table.GetDataStartAddress() + field_index * sizeof(T),
meta_table.GetDataEndAddress());
T* raw_data = reinterpret_cast<T*>(meta_table.GetDataStartAddress());
return raw_data[field_index];
}
constexpr int SwissNameDictionary::MetaTableSizePerEntryFor(int capacity) {
CONSTEXPR_DCHECK(IsValidCapacity(capacity));
// See the STATIC_ASSERTs on |kMax1ByteMetaTableCapacity| and
// |kMax2ByteMetaTableCapacity| in the .cc file for an explanation of these
// constants.
if (capacity <= kMax1ByteMetaTableCapacity) {
return sizeof(uint8_t);
} else if (capacity <= kMax2ByteMetaTableCapacity) {
return sizeof(uint16_t);
} else {
return sizeof(uint32_t);
}
}
constexpr int SwissNameDictionary::MetaTableSizeFor(int capacity) {
CONSTEXPR_DCHECK(IsValidCapacity(capacity));
int per_entry_size = MetaTableSizePerEntryFor(capacity);
// The enumeration table only needs to have as many slots as there can be
// present + deleted entries in the hash table (= maximum load factor *
// capactiy). Two more slots to store the number of present and deleted
// entries.
return per_entry_size * (MaxUsableCapacity(capacity) + 2);
}
template <typename LocalIsolate>
void SwissNameDictionary::Initialize(LocalIsolate* isolate,
ByteArray meta_table, int capacity) {
DCHECK(IsValidCapacity(capacity));
DisallowHeapAllocation no_gc;
ReadOnlyRoots roots(isolate);
SetCapacity(capacity);
SetHash(PropertyArray::kNoHashSentinel);
ctrl_t* ctrl_table = reinterpret_cast<ctrl_t*>(
field_address(CtrlTableStartOffset(Capacity())));
memset(ctrl_table, Ctrl::kEmpty, CtrlTableSize(capacity));
MemsetTagged(RawField(DataTableStartOffset()), roots.the_hole_value(),
capacity * kDataTableEntryCount);
set_meta_table(meta_table);
SetNumberOfElements(0);
SetNumberOfDeletedElements(0);
// We leave the enumeration table PropertyDetails table and uninitialized.
}
void SwissNameDictionary::SetHash(int32_t hash) {
WriteField(PrefixOffset(), hash);
}
int SwissNameDictionary::Hash() { return ReadField<int32_t>(PrefixOffset()); }
// static
constexpr int SwissNameDictionary::MaxCapacity() {
int const_size =
DataTableStartOffset() + ByteArray::kHeaderSize +
// Size for present and deleted element count at max capacity:
2 * sizeof(uint32_t);
int per_entry_size =
// size of data table entries:
kDataTableEntryCount * kTaggedSize +
// ctrl table entry size:
kOneByteSize +
// PropertyDetails table entry size:
kOneByteSize +
// Enumeration table entry size at maximum capacity:
sizeof(uint32_t);
int result = (FixedArray::kMaxSize - const_size) / per_entry_size;
CONSTEXPR_DCHECK(result <= Smi::kMaxValue);
return result;
}
// static
constexpr int SwissNameDictionary::PrefixOffset() {
return HeapObject::kHeaderSize;
......@@ -91,6 +298,10 @@ constexpr int SwissNameDictionary::PropertyDetailsTableStartOffset(
return CtrlTableStartOffset(capacity) + CtrlTableSize(capacity);
}
ACCESSORS_CHECKED2(SwissNameDictionary, meta_table, ByteArray,
MetaTablePointerOffset(), true,
value.length() >= kMetaTableEnumerationTableStartOffset)
} // namespace internal
} // namespace v8
......
......@@ -8,5 +8,30 @@
#include "src/objects/swiss-name-dictionary-inl.h"
namespace v8 {
namespace internal {} // namespace internal
namespace internal {
// The largest value we ever have to store in the enumeration table is
// Capacity() - 1. The largest value we ever have to store for the present or
// deleted element count is MaxUsableCapacity(Capacity()). All data in the
// meta table is unsigned. Using this, we verify the values of the constants
// |kMax1ByteMetaTableCapacity| and |kMax2ByteMetaTableCapacity|.
STATIC_ASSERT(SwissNameDictionary::kMax1ByteMetaTableCapacity - 1 <=
std::numeric_limits<uint8_t>::max());
STATIC_ASSERT(SwissNameDictionary::MaxUsableCapacity(
SwissNameDictionary::kMax1ByteMetaTableCapacity) <=
std::numeric_limits<uint8_t>::max());
STATIC_ASSERT(SwissNameDictionary::kMax2ByteMetaTableCapacity - 1 <=
std::numeric_limits<uint16_t>::max());
STATIC_ASSERT(SwissNameDictionary::MaxUsableCapacity(
SwissNameDictionary::kMax2ByteMetaTableCapacity) <=
std::numeric_limits<uint16_t>::max());
template void SwissNameDictionary::Initialize(Isolate* isolate,
ByteArray meta_table,
int capacity);
template void SwissNameDictionary::Initialize(LocalIsolate* isolate,
ByteArray meta_table,
int capacity);
} // namespace internal
} // namespace v8
......@@ -40,7 +40,6 @@ namespace internal {
// identity hash: 4 bytes, raw int32_t
// Meta table pointer: kTaggedSize bytes.
// See below for explanation of the meta table.
// For capacity 0, this contains the Smi |kNoMetaTableSentinel| instead.
// Data table:
// For each logical bucket of the hash table, contains the corresponding key
// and value.
......@@ -73,16 +72,40 @@ class SwissNameDictionary : public HeapObject {
public:
using Group = swiss_table::Group;
inline int NumberOfElements();
inline int NumberOfDeletedElements();
inline int Capacity();
inline int UsedCapacity();
template <typename LocalIsolate>
void Initialize(LocalIsolate* isolate, ByteArray meta_table, int capacity);
inline void SetHash(int hash);
inline int Hash();
inline static constexpr bool IsValidCapacity(int capacity);
inline static int CapacityFor(int at_least_space_for);
// Given a capacity, how much of it can we fill before resizing?
inline static constexpr int MaxUsableCapacity(int capacity);
// The maximum allowed capacity for any SwissNameDictionary.
inline static constexpr int MaxCapacity();
// Returns total size in bytes required for a table of given capacity.
inline static constexpr int SizeFor(int capacity);
// TODO(v8:11388) This is a temporary placeholder for the actual value, which
// is added here in a follow-up CL.
static const int kGroupWidth = 8;
inline static constexpr int MetaTableSizePerEntryFor(int capacity);
inline static constexpr int MetaTableSizeFor(int capacity);
inline static constexpr int DataTableSize(int capacity);
inline static constexpr int CtrlTableSize(int capacity);
// Indicates that IterateEntries() returns entries ordered.
static constexpr bool kIsOrderedDictionaryType = true;
static const int kGroupWidth = Group::kWidth;
class BodyDescriptor;
......@@ -93,9 +116,19 @@ class SwissNameDictionary : public HeapObject {
// Defines how many kTaggedSize sized values are associcated which each entry
// in the data table.
static constexpr int kDataTableEntryCount = 2;
static constexpr int kDataTableKeyEntryIndex = 0;
static constexpr int kDataTableValueEntryIndex = kDataTableKeyEntryIndex + 1;
inline static constexpr int DataTableSize(int capacity);
inline static constexpr int CtrlTableSize(int capacity);
static constexpr int kMetaTableElementCountOffset = 0;
static constexpr int kMetaTableDeletedElementCountOffset = 1;
static constexpr int kMetaTableEnumerationTableStartOffset = 2;
// The maximum capacity of any SwissNameDictionary whose meta table can use 1
// byte per entry.
static constexpr int kMax1ByteMetaTableCapacity = (1 << 8);
// The maximum capacity of any SwissNameDictionary whose meta table can use 2
// bytes per entry.
static constexpr int kMax2ByteMetaTableCapacity = (1 << 16);
// TODO(v8:11388) We would like to use Torque-generated constants here, but
// those are currently incorrect.
......@@ -114,6 +147,28 @@ class SwissNameDictionary : public HeapObject {
DECL_PRINTER(SwissNameDictionary)
DECL_CAST(SwissNameDictionary)
OBJECT_CONSTRUCTORS(SwissNameDictionary, HeapObject);
private:
using ctrl_t = swiss_table::ctrl_t;
using Ctrl = swiss_table::Ctrl;
// Not intended for modification, use set_ctrl instead to get correct copying
// of first group.
inline const ctrl_t* CtrlTable();
inline void SetCapacity(int capacity);
inline void SetNumberOfElements(int elements);
inline void SetNumberOfDeletedElements(int deleted_elements);
DECL_ACCESSORS(meta_table, ByteArray)
inline void SetMetaTableField(int field_index, int value);
inline int GetMetaTableField(int field_index);
template <typename T>
inline static void SetMetaTableField(ByteArray meta_table, int field_index,
int value);
template <typename T>
inline static int GetMetaTableField(ByteArray meta_table, int field_index);
};
} // namespace internal
......
......@@ -167,6 +167,8 @@ class Symbol;
V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \
V(OrderedNameDictionary, empty_ordered_property_dictionary, \
EmptyOrderedPropertyDictionary) \
V(SwissNameDictionary, empty_swiss_property_dictionary, \
EmptySwissPropertyDictionary) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
......
......@@ -275,6 +275,7 @@ v8_source_set("cctest_sources") {
"test-smi-lexicographic-compare.cc",
"test-strings.cc",
"test-strtod.cc",
"test-swiss-name-dictionary.cc",
"test-symbols.cc",
"test-thread-termination.cc",
"test-threads.cc",
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/objects/swiss-name-dictionary-inl.h"
#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
namespace test_swiss_hash_table {
TEST(CapacityFor) {
for (int elements = 0; elements <= 32; elements++) {
int capacity = SwissNameDictionary::CapacityFor(elements);
if (elements == 0) {
CHECK_EQ(0, capacity);
} else if (elements <= 3) {
CHECK_EQ(4, capacity);
} else if (elements == 4) {
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 8, capacity == 8);
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 16, capacity == 4);
} else if (elements <= 7) {
CHECK_EQ(8, capacity);
} else if (elements <= 14) {
CHECK_EQ(16, capacity);
} else if (elements <= 28) {
CHECK_EQ(32, capacity);
} else if (elements <= 32) {
CHECK_EQ(64, capacity);
}
}
}
TEST(MaxUsableCapacity) {
CHECK_EQ(0, SwissNameDictionary::MaxUsableCapacity(0));
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 8,
SwissNameDictionary::MaxUsableCapacity(4) == 3);
CHECK_IMPLIES(SwissNameDictionary::kGroupWidth == 16,
SwissNameDictionary::MaxUsableCapacity(4) == 4);
CHECK_EQ(7, SwissNameDictionary::MaxUsableCapacity(8));
CHECK_EQ(14, SwissNameDictionary::MaxUsableCapacity(16));
CHECK_EQ(28, SwissNameDictionary::MaxUsableCapacity(32));
}
TEST(SizeFor) {
int baseline = HeapObject::kHeaderSize +
// prefix:
4 +
// capacity:
4 +
// meta table:
kTaggedSize;
int size_0 = baseline +
// ctrl table:
SwissNameDictionary::kGroupWidth;
int size_4 = baseline +
// data table:
4 * 2 * kTaggedSize +
// ctrl table:
4 + SwissNameDictionary::kGroupWidth +
// property details table:
4;
int size_8 = baseline +
// data table:
8 * 2 * kTaggedSize +
// ctrl table:
8 + SwissNameDictionary::kGroupWidth +
// property details table:
8;
CHECK_EQ(SwissNameDictionary::SizeFor(0), size_0);
CHECK_EQ(SwissNameDictionary::SizeFor(4), size_4);
CHECK_EQ(SwissNameDictionary::SizeFor(8), size_8);
}
} // namespace test_swiss_hash_table
} // namespace internal
} // namespace v8
......@@ -322,70 +322,70 @@ KNOWN_MAPS = {
("read_only_space", 0x03151): (67, "SelfReferenceMarkerMap"),
("read_only_space", 0x03179): (67, "BasicBlockCountersMarkerMap"),
("read_only_space", 0x031bd): (87, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x03291): (100, "InterceptorInfoMap"),
("read_only_space", 0x053e5): (72, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x0540d): (73, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05435): (74, "CallableTaskMap"),
("read_only_space", 0x0545d): (75, "CallbackTaskMap"),
("read_only_space", 0x05485): (76, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x054ad): (79, "FunctionTemplateInfoMap"),
("read_only_space", 0x054d5): (80, "ObjectTemplateInfoMap"),
("read_only_space", 0x054fd): (81, "AccessCheckInfoMap"),
("read_only_space", 0x05525): (82, "AccessorInfoMap"),
("read_only_space", 0x0554d): (83, "AccessorPairMap"),
("read_only_space", 0x05575): (84, "AliasedArgumentsEntryMap"),
("read_only_space", 0x0559d): (85, "AllocationMementoMap"),
("read_only_space", 0x055c5): (88, "AsmWasmDataMap"),
("read_only_space", 0x055ed): (89, "AsyncGeneratorRequestMap"),
("read_only_space", 0x05615): (90, "BaselineDataMap"),
("read_only_space", 0x0563d): (91, "BreakPointMap"),
("read_only_space", 0x05665): (92, "BreakPointInfoMap"),
("read_only_space", 0x0568d): (93, "CachedTemplateObjectMap"),
("read_only_space", 0x056b5): (95, "ClassPositionsMap"),
("read_only_space", 0x056dd): (96, "DebugInfoMap"),
("read_only_space", 0x05705): (99, "FunctionTemplateRareDataMap"),
("read_only_space", 0x0572d): (101, "InterpreterDataMap"),
("read_only_space", 0x05755): (102, "ModuleRequestMap"),
("read_only_space", 0x0577d): (103, "PromiseCapabilityMap"),
("read_only_space", 0x057a5): (104, "PromiseReactionMap"),
("read_only_space", 0x057cd): (105, "PropertyDescriptorObjectMap"),
("read_only_space", 0x057f5): (106, "PrototypeInfoMap"),
("read_only_space", 0x0581d): (107, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x05845): (108, "ScriptMap"),
("read_only_space", 0x0586d): (109, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x05895): (110, "StackFrameInfoMap"),
("read_only_space", 0x058bd): (111, "TemplateObjectDescriptionMap"),
("read_only_space", 0x058e5): (112, "Tuple2Map"),
("read_only_space", 0x0590d): (113, "WasmExceptionTagMap"),
("read_only_space", 0x05935): (114, "WasmExportedFunctionDataMap"),
("read_only_space", 0x0595d): (115, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x05985): (116, "WasmJSFunctionDataMap"),
("read_only_space", 0x059ad): (135, "SloppyArgumentsElementsMap"),
("read_only_space", 0x059d5): (152, "DescriptorArrayMap"),
("read_only_space", 0x059fd): (157, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x05a25): (156, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x05a4d): (172, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x05a75): (182, "WasmCapiFunctionDataMap"),
("read_only_space", 0x05a9d): (169, "InternalClassMap"),
("read_only_space", 0x05ac5): (178, "SmiPairMap"),
("read_only_space", 0x05aed): (177, "SmiBoxMap"),
("read_only_space", 0x05b15): (146, "ExportedSubClassBaseMap"),
("read_only_space", 0x05b3d): (147, "ExportedSubClassMap"),
("read_only_space", 0x05b65): (68, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x05b8d): (69, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x05bb5): (133, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x05bdd): (170, "InternalClassWithStructElementsMap"),
("read_only_space", 0x05c05): (148, "ExportedSubClass2Map"),
("read_only_space", 0x05c2d): (179, "SortStateMap"),
("read_only_space", 0x05c55): (86, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05c7d): (86, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05ca5): (77, "LoadHandler1Map"),
("read_only_space", 0x05ccd): (77, "LoadHandler2Map"),
("read_only_space", 0x05cf5): (77, "LoadHandler3Map"),
("read_only_space", 0x05d1d): (78, "StoreHandler0Map"),
("read_only_space", 0x05d45): (78, "StoreHandler1Map"),
("read_only_space", 0x05d6d): (78, "StoreHandler2Map"),
("read_only_space", 0x05d95): (78, "StoreHandler3Map"),
("read_only_space", 0x032bd): (100, "InterceptorInfoMap"),
("read_only_space", 0x05411): (72, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05439): (73, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05461): (74, "CallableTaskMap"),
("read_only_space", 0x05489): (75, "CallbackTaskMap"),
("read_only_space", 0x054b1): (76, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x054d9): (79, "FunctionTemplateInfoMap"),
("read_only_space", 0x05501): (80, "ObjectTemplateInfoMap"),
("read_only_space", 0x05529): (81, "AccessCheckInfoMap"),
("read_only_space", 0x05551): (82, "AccessorInfoMap"),
("read_only_space", 0x05579): (83, "AccessorPairMap"),
("read_only_space", 0x055a1): (84, "AliasedArgumentsEntryMap"),
("read_only_space", 0x055c9): (85, "AllocationMementoMap"),
("read_only_space", 0x055f1): (88, "AsmWasmDataMap"),
("read_only_space", 0x05619): (89, "AsyncGeneratorRequestMap"),
("read_only_space", 0x05641): (90, "BaselineDataMap"),
("read_only_space", 0x05669): (91, "BreakPointMap"),
("read_only_space", 0x05691): (92, "BreakPointInfoMap"),
("read_only_space", 0x056b9): (93, "CachedTemplateObjectMap"),
("read_only_space", 0x056e1): (95, "ClassPositionsMap"),
("read_only_space", 0x05709): (96, "DebugInfoMap"),
("read_only_space", 0x05731): (99, "FunctionTemplateRareDataMap"),
("read_only_space", 0x05759): (101, "InterpreterDataMap"),
("read_only_space", 0x05781): (102, "ModuleRequestMap"),
("read_only_space", 0x057a9): (103, "PromiseCapabilityMap"),
("read_only_space", 0x057d1): (104, "PromiseReactionMap"),
("read_only_space", 0x057f9): (105, "PropertyDescriptorObjectMap"),
("read_only_space", 0x05821): (106, "PrototypeInfoMap"),
("read_only_space", 0x05849): (107, "RegExpBoilerplateDescriptionMap"),
("read_only_space", 0x05871): (108, "ScriptMap"),
("read_only_space", 0x05899): (109, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x058c1): (110, "StackFrameInfoMap"),
("read_only_space", 0x058e9): (111, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05911): (112, "Tuple2Map"),
("read_only_space", 0x05939): (113, "WasmExceptionTagMap"),
("read_only_space", 0x05961): (114, "WasmExportedFunctionDataMap"),
("read_only_space", 0x05989): (115, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x059b1): (116, "WasmJSFunctionDataMap"),
("read_only_space", 0x059d9): (135, "SloppyArgumentsElementsMap"),
("read_only_space", 0x05a01): (152, "DescriptorArrayMap"),
("read_only_space", 0x05a29): (157, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x05a51): (156, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x05a79): (172, "OnHeapBasicBlockProfilerDataMap"),
("read_only_space", 0x05aa1): (182, "WasmCapiFunctionDataMap"),
("read_only_space", 0x05ac9): (169, "InternalClassMap"),
("read_only_space", 0x05af1): (178, "SmiPairMap"),
("read_only_space", 0x05b19): (177, "SmiBoxMap"),
("read_only_space", 0x05b41): (146, "ExportedSubClassBaseMap"),
("read_only_space", 0x05b69): (147, "ExportedSubClassMap"),
("read_only_space", 0x05b91): (68, "AbstractInternalClassSubclass1Map"),
("read_only_space", 0x05bb9): (69, "AbstractInternalClassSubclass2Map"),
("read_only_space", 0x05be1): (133, "InternalClassWithSmiElementsMap"),
("read_only_space", 0x05c09): (170, "InternalClassWithStructElementsMap"),
("read_only_space", 0x05c31): (148, "ExportedSubClass2Map"),
("read_only_space", 0x05c59): (179, "SortStateMap"),
("read_only_space", 0x05c81): (86, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05ca9): (86, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05cd1): (77, "LoadHandler1Map"),
("read_only_space", 0x05cf9): (77, "LoadHandler2Map"),
("read_only_space", 0x05d21): (77, "LoadHandler3Map"),
("read_only_space", 0x05d49): (78, "StoreHandler0Map"),
("read_only_space", 0x05d71): (78, "StoreHandler1Map"),
("read_only_space", 0x05d99): (78, "StoreHandler2Map"),
("read_only_space", 0x05dc1): (78, "StoreHandler3Map"),
("map_space", 0x02119): (1057, "ExternalMap"),
("map_space", 0x02141): (1098, "JSMessageObjectMap"),
}
......@@ -422,20 +422,21 @@ KNOWN_OBJECTS = {
("read_only_space", 0x03245): "EmptyFeedbackMetadata",
("read_only_space", 0x03251): "EmptyPropertyDictionary",
("read_only_space", 0x03279): "EmptyOrderedPropertyDictionary",
("read_only_space", 0x032b9): "NoOpInterceptorInfo",
("read_only_space", 0x032e1): "EmptyWeakArrayList",
("read_only_space", 0x032ed): "InfinityValue",
("read_only_space", 0x032f9): "MinusZeroValue",
("read_only_space", 0x03305): "MinusInfinityValue",
("read_only_space", 0x03311): "SelfReferenceMarker",
("read_only_space", 0x03351): "BasicBlockCountersMarker",
("read_only_space", 0x03395): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x033a1): "TrampolineTrivialCodeDataContainer",
("read_only_space", 0x033ad): "TrampolinePromiseRejectionCodeDataContainer",
("read_only_space", 0x033b9): "GlobalThisBindingScopeInfo",
("read_only_space", 0x033f1): "EmptyFunctionScopeInfo",
("read_only_space", 0x03419): "NativeScopeInfo",
("read_only_space", 0x03435): "HashSeed",
("read_only_space", 0x03291): "EmptySwissPropertyDictionary",
("read_only_space", 0x032e5): "NoOpInterceptorInfo",
("read_only_space", 0x0330d): "EmptyWeakArrayList",
("read_only_space", 0x03319): "InfinityValue",
("read_only_space", 0x03325): "MinusZeroValue",
("read_only_space", 0x03331): "MinusInfinityValue",
("read_only_space", 0x0333d): "SelfReferenceMarker",
("read_only_space", 0x0337d): "BasicBlockCountersMarker",
("read_only_space", 0x033c1): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x033cd): "TrampolineTrivialCodeDataContainer",
("read_only_space", 0x033d9): "TrampolinePromiseRejectionCodeDataContainer",
("read_only_space", 0x033e5): "GlobalThisBindingScopeInfo",
("read_only_space", 0x0341d): "EmptyFunctionScopeInfo",
("read_only_space", 0x03445): "NativeScopeInfo",
("read_only_space", 0x03461): "HashSeed",
("old_space", 0x02119): "ArgumentsIteratorAccessor",
("old_space", 0x0215d): "ArrayLengthAccessor",
("old_space", 0x021a1): "BoundFunctionLengthAccessor",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment