[in-place weak refs] Add WeakArrayList & replace Heap::retained_maps with it.

BUG=v8:7308

Change-Id: I5e9f371b1db5515b723d9a2864bf2038706e2015
Reviewed-on: https://chromium-review.googlesource.com/960032
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52613}
This commit is contained in:
Marja Hölttä 2018-04-16 09:28:28 +02:00 committed by Commit Bot
parent 2e59ff8c45
commit d3a2819ee9
25 changed files with 460 additions and 129 deletions

View File

@ -265,6 +265,7 @@ Type::bitset BitsetType::Lub(i::Map* map) {
case FIXED_ARRAY_TYPE:
case HASH_TABLE_TYPE:
case WEAK_FIXED_ARRAY_TYPE:
case WEAK_ARRAY_LIST_TYPE:
case FIXED_DOUBLE_ARRAY_TYPE:
case FEEDBACK_METADATA_TYPE:
case BYTE_ARRAY_TYPE:

View File

@ -86,6 +86,14 @@ HeapObject* Factory::AllocateRawFixedArray(int length,
return AllocateRawArray(FixedArray::SizeFor(length), pretenure);
}
HeapObject* Factory::AllocateRawWeakArrayList(int capacity,
PretenureFlag pretenure) {
if (capacity < 0 || capacity > WeakArrayList::kMaxCapacity) {
isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
}
return AllocateRawArray(WeakArrayList::SizeForCapacity(capacity), pretenure);
}
HeapObject* Factory::New(Handle<Map> map, PretenureFlag pretenure) {
DCHECK(map->instance_type() != MAP_TYPE);
int size = map->instance_size();
@ -1837,6 +1845,29 @@ Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array,
return CopyArrayAndGrow(array, grow_by, pretenure);
}
Handle<WeakArrayList> Factory::CopyWeakArrayListAndGrow(
Handle<WeakArrayList> src, int grow_by, PretenureFlag pretenure) {
int old_capacity = src->capacity();
int new_capacity = old_capacity + grow_by;
DCHECK_GE(new_capacity, old_capacity);
HeapObject* obj = AllocateRawWeakArrayList(new_capacity, pretenure);
obj->set_map_after_allocation(src->map(), SKIP_WRITE_BARRIER);
WeakArrayList* result = WeakArrayList::cast(obj);
result->set_length(src->length());
result->set_capacity(new_capacity);
// Copy the content.
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
for (int i = 0; i < old_capacity; i++) result->Set(i, src->Get(i), mode);
HeapObjectReference* undefined_reference =
HeapObjectReference::Strong(isolate()->heap()->undefined_value());
MemsetPointer(result->data_start() + old_capacity, undefined_reference,
grow_by);
return Handle<WeakArrayList>(result, isolate());
}
Handle<PropertyArray> Factory::CopyPropertyArrayAndGrow(
Handle<PropertyArray> array, int grow_by, PretenureFlag pretenure) {
return CopyArrayAndGrow(array, grow_by, pretenure);

View File

@ -477,6 +477,10 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<FixedArray> array, int grow_by,
PretenureFlag pretenure = NOT_TENURED);
Handle<WeakArrayList> CopyWeakArrayListAndGrow(
Handle<WeakArrayList> array, int grow_by,
PretenureFlag pretenure = NOT_TENURED);
Handle<PropertyArray> CopyPropertyArrayAndGrow(
Handle<PropertyArray> array, int grow_by,
PretenureFlag pretenure = NOT_TENURED);
@ -902,6 +906,7 @@ class V8_EXPORT_PRIVATE Factory final {
// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
HeapObject* AllocateRawArray(int size, PretenureFlag pretenure);
HeapObject* AllocateRawFixedArray(int length, PretenureFlag pretenure);
HeapObject* AllocateRawWeakArrayList(int length, PretenureFlag pretenure);
Handle<FixedArray> NewFixedArrayWithFiller(Heap::RootListIndex map_root_index,
int length, Object* filler,
PretenureFlag pretenure);

View File

@ -1435,7 +1435,7 @@ int Heap::NotifyContextDisposed(bool dependant_context) {
}
isolate()->AbortConcurrentOptimization(BlockingBehavior::kDontBlock);
number_of_disposed_maps_ = retained_maps()->Length();
number_of_disposed_maps_ = retained_maps()->length();
tracer()->AddContextDisposalTime(MonotonicallyIncreasingTimeInMs());
return ++contexts_disposed_;
}
@ -5015,33 +5015,36 @@ void Heap::AddRetainedMap(Handle<Map> map) {
if (map->is_in_retained_map_list()) {
return;
}
Handle<WeakCell> cell = Map::WeakCellForMap(map);
Handle<ArrayList> array(retained_maps(), isolate());
Handle<WeakArrayList> array(retained_maps(), isolate());
if (array->IsFull()) {
CompactRetainedMaps(*array);
}
array = ArrayList::Add(
array, cell, handle(Smi::FromInt(FLAG_retain_maps_for_n_gc), isolate()));
array =
WeakArrayList::Add(array, map, Smi::FromInt(FLAG_retain_maps_for_n_gc));
if (*array != retained_maps()) {
set_retained_maps(*array);
}
map->set_is_in_retained_map_list(true);
}
void Heap::CompactRetainedMaps(ArrayList* retained_maps) {
void Heap::CompactRetainedMaps(WeakArrayList* retained_maps) {
DCHECK_EQ(retained_maps, this->retained_maps());
int length = retained_maps->Length();
int length = retained_maps->length();
int new_length = 0;
int new_number_of_disposed_maps = 0;
// This loop compacts the array by removing cleared weak cells.
for (int i = 0; i < length; i += 2) {
DCHECK(retained_maps->Get(i)->IsWeakCell());
WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
Object* age = retained_maps->Get(i + 1);
if (cell->cleared()) continue;
MaybeObject* maybe_object = retained_maps->Get(i);
if (maybe_object->IsClearedWeakHeapObject()) {
continue;
}
DCHECK(maybe_object->IsWeakHeapObject());
MaybeObject* age = retained_maps->Get(i + 1);
DCHECK(age->IsSmi());
if (i != new_length) {
retained_maps->Set(new_length, cell);
retained_maps->Set(new_length, maybe_object);
retained_maps->Set(new_length + 1, age);
}
if (i < number_of_disposed_maps_) {
@ -5050,11 +5053,11 @@ void Heap::CompactRetainedMaps(ArrayList* retained_maps) {
new_length += 2;
}
number_of_disposed_maps_ = new_number_of_disposed_maps;
Object* undefined = undefined_value();
HeapObject* undefined = undefined_value();
for (int i = new_length; i < length; i++) {
retained_maps->Clear(i, undefined);
retained_maps->Set(i, HeapObjectReference::Strong(undefined));
}
if (new_length != length) retained_maps->SetLength(new_length);
if (new_length != length) retained_maps->set_length(new_length);
}
void Heap::FatalProcessOutOfMemory(const char* location) {

View File

@ -138,6 +138,7 @@ using v8::MemoryPressureLevel;
V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \
V(Map, string_table_map, StringTableMap) \
V(Map, weak_fixed_array_map, WeakFixedArrayMap) \
V(Map, weak_array_list_map, WeakArrayListMap) \
/* String maps */ \
V(Map, native_source_string_map, NativeSourceStringMap) \
V(Map, string_map, StringMap) \
@ -222,6 +223,7 @@ using v8::MemoryPressureLevel;
V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
V(WeakArrayList, empty_weak_array_list, EmptyWeakArrayList) \
/* Protectors */ \
V(Cell, array_constructor_protector, ArrayConstructorProtector) \
V(PropertyCell, no_elements_protector, NoElementsProtector) \
@ -256,7 +258,7 @@ using v8::MemoryPressureLevel;
V(FixedArray, microtask_queue, MicrotaskQueue) \
V(FixedArray, detached_contexts, DetachedContexts) \
V(HeapObject, retaining_path_targets, RetainingPathTargets) \
V(ArrayList, retained_maps, RetainedMaps) \
V(WeakArrayList, retained_maps, RetainedMaps) \
/* Indirection lists for isolate-independent builtins */ \
V(FixedArray, builtins_constants_table, BuiltinsConstantsTable) \
/* Feedback vectors that we need for code coverage or type profile */ \
@ -404,6 +406,7 @@ using v8::MemoryPressureLevel;
V(UninitializedValue) \
V(WeakCellMap) \
V(WeakFixedArrayMap) \
V(WeakArrayListMap) \
V(WithContextMap) \
V(empty_string) \
PRIVATE_SYMBOL_LIST(V)
@ -1935,7 +1938,7 @@ class Heap {
void AddToRingBuffer(const char* string);
void GetFromRingBuffer(char* buffer);
void CompactRetainedMaps(ArrayList* retained_maps);
void CompactRetainedMaps(WeakArrayList* retained_maps);
void CollectGarbageOnMemoryPressure();

View File

@ -511,19 +511,21 @@ void IncrementalMarking::RetainMaps() {
bool map_retaining_is_disabled = heap()->ShouldReduceMemory() ||
heap()->ShouldAbortIncrementalMarking() ||
FLAG_retain_maps_for_n_gc == 0;
ArrayList* retained_maps = heap()->retained_maps();
int length = retained_maps->Length();
WeakArrayList* retained_maps = heap()->retained_maps();
int length = retained_maps->length();
// The number_of_disposed_maps separates maps in the retained_maps
// array that were created before and after context disposal.
// We do not age and retain disposed maps to avoid memory leaks.
int number_of_disposed_maps = heap()->number_of_disposed_maps_;
for (int i = 0; i < length; i += 2) {
DCHECK(retained_maps->Get(i)->IsWeakCell());
WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
if (cell->cleared()) continue;
int age = Smi::ToInt(retained_maps->Get(i + 1));
MaybeObject* value = retained_maps->Get(i);
HeapObject* map_heap_object;
if (!value->ToWeakHeapObject(&map_heap_object)) {
continue;
}
int age = Smi::ToInt(retained_maps->Get(i + 1)->ToSmi());
int new_age;
Map* map = Map::cast(cell->value());
Map* map = Map::cast(map_heap_object);
if (i >= number_of_disposed_maps && !map_retaining_is_disabled &&
marking_state()->IsWhite(map)) {
if (ShouldRetainMap(map, age)) {
@ -544,7 +546,7 @@ void IncrementalMarking::RetainMaps() {
}
// Compact the array and update the age.
if (new_age != age) {
retained_maps->Set(i + 1, Smi::FromInt(new_age));
retained_maps->Set(i + 1, MaybeObject::FromSmi(Smi::FromInt(new_age)));
}
}
}

View File

@ -56,6 +56,8 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map* map,
return visitor->VisitStruct(map, object);
case kVisitFreeSpace:
return visitor->VisitFreeSpace(map, FreeSpace::cast(object));
case kVisitWeakArray:
return visitor->VisitWeakArray(map, object);
case kVisitorIdCount:
UNREACHABLE();
}
@ -191,6 +193,18 @@ int NewSpaceVisitor<ConcreteVisitor>::VisitJSApiObject(Map* map,
return visitor->VisitJSObject(map, object);
}
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitWeakArray(
Map* map, HeapObject* object) {
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
if (!visitor->ShouldVisit(object)) return ResultType();
int size = WeakArrayBodyDescriptor::SizeOf(map, object);
if (visitor->ShouldVisitMapPointer())
visitor->VisitMapPointer(object, object->map_slot());
WeakArrayBodyDescriptor::IterateBody(map, object, size, visitor);
return size;
}
} // namespace internal
} // namespace v8

View File

@ -55,8 +55,7 @@ class JSWeakCollection;
V(ThinString) \
V(TransitionArray) \
V(WasmInstanceObject) \
V(WeakCell) \
V(WeakFixedArray)
V(WeakCell)
// The base class for visitors that need to dispatch on object type. The default
// behavior of all visit functions is to iterate body of the given object using
@ -98,6 +97,7 @@ class HeapVisitor : public ObjectVisitor {
V8_INLINE ResultType VisitJSApiObject(Map* map, JSObject* object);
V8_INLINE ResultType VisitStruct(Map* map, HeapObject* object);
V8_INLINE ResultType VisitFreeSpace(Map* map, FreeSpace* object);
V8_INLINE ResultType VisitWeakArray(Map* map, HeapObject* object);
template <typename T>
static V8_INLINE T* Cast(HeapObject* object);

View File

@ -203,6 +203,8 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
ALLOCATE_PARTIAL_MAP(WEAK_FIXED_ARRAY_TYPE, kVariableSizeSentinel,
weak_fixed_array);
ALLOCATE_PARTIAL_MAP(WEAK_ARRAY_LIST_TYPE, kVariableSizeSentinel,
weak_array_list);
ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel,
fixed_cow_array)
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
@ -234,6 +236,16 @@ bool Heap::CreateInitialMaps() {
}
set_empty_weak_fixed_array(WeakFixedArray::cast(obj));
{
AllocationResult allocation =
AllocateRaw(WeakArrayList::SizeForCapacity(0), OLD_SPACE);
if (!allocation.To(&obj)) return false;
obj->set_map_after_allocation(weak_array_list_map(), SKIP_WRITE_BARRIER);
WeakArrayList::cast(obj)->set_capacity(0);
WeakArrayList::cast(obj)->set_length(0);
}
set_empty_weak_array_list(WeakArrayList::cast(obj));
{
AllocationResult allocation = Allocate(null_map(), OLD_SPACE);
if (!allocation.To(&obj)) return false;
@ -294,6 +306,7 @@ bool Heap::CreateInitialMaps() {
FinalizePartialMap(this, meta_map());
FinalizePartialMap(this, fixed_array_map());
FinalizePartialMap(this, weak_fixed_array_map());
FinalizePartialMap(this, weak_array_list_map());
FinalizePartialMap(this, fixed_cow_array_map());
FinalizePartialMap(this, descriptor_array_map());
FinalizePartialMap(this, undefined_map());
@ -698,7 +711,7 @@ void Heap::CreateInitialObjects() {
}
set_detached_contexts(empty_fixed_array());
set_retained_maps(ArrayList::cast(empty_fixed_array()));
set_retained_maps(empty_weak_array_list());
set_retaining_path_targets(undefined_value());
set_feedback_vectors_for_profiling_tools(undefined_value());

View File

@ -285,16 +285,16 @@ class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
}
};
class WeakFixedArray::BodyDescriptor final : public BodyDescriptorBase {
class WeakArrayBodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map* map, HeapObject* obj, int offset) {
return offset >= kHeaderSize;
return true;
}
template <typename ObjectVisitor>
static inline void IterateBody(Map* map, HeapObject* obj, int object_size,
ObjectVisitor* v) {
IterateMaybeWeakPointers(obj, kHeaderSize, object_size, v);
IterateMaybeWeakPointers(obj, HeapObject::kHeaderSize, object_size, v);
}
static inline int SizeOf(Map* map, HeapObject* object) {
@ -566,6 +566,8 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
case WEAK_FIXED_ARRAY_TYPE:
return Op::template apply<WeakFixedArray::BodyDescriptor>(p1, p2, p3, p4);
case WEAK_ARRAY_LIST_TYPE:
return Op::template apply<WeakArrayList::BodyDescriptor>(p1, p2, p3, p4);
case FIXED_DOUBLE_ARRAY_TYPE:
return ReturnType();
case FEEDBACK_METADATA_TYPE:

View File

@ -141,6 +141,9 @@ void HeapObject::HeapObjectVerify() {
case WEAK_FIXED_ARRAY_TYPE:
WeakFixedArray::cast(this)->WeakFixedArrayVerify();
break;
case WEAK_ARRAY_LIST_TYPE:
WeakArrayList::cast(this)->WeakArrayListVerify();
break;
case FIXED_DOUBLE_ARRAY_TYPE:
FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
break;
@ -554,6 +557,12 @@ void WeakFixedArray::WeakFixedArrayVerify() {
}
}
void WeakArrayList::WeakArrayListVerify() {
for (int i = 0; i < length(); i++) {
MaybeObject::VerifyMaybeObjectPointer(Get(i));
}
}
void PropertyArray::PropertyArrayVerify() {
if (length() == 0) {
CHECK_EQ(this, this->GetHeap()->empty_property_array());

View File

@ -2242,6 +2242,10 @@ int HeapObject::SizeFromMap(Map* map) const {
return WeakFixedArray::SizeFor(
reinterpret_cast<const WeakFixedArray*>(this)->synchronized_length());
}
if (instance_type == WEAK_ARRAY_LIST_TYPE) {
return WeakArrayList::SizeForCapacity(
reinterpret_cast<const WeakArrayList*>(this)->synchronized_capacity());
}
if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
return reinterpret_cast<const FixedTypedArrayBase*>(this)->TypedArraySize(

View File

@ -277,6 +277,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case WEAK_FIXED_ARRAY_TYPE:
WeakFixedArray::cast(this)->WeakFixedArrayPrint(os);
break;
case WEAK_ARRAY_LIST_TYPE:
WeakArrayList::cast(this)->WeakArrayListPrint(os);
break;
case INTERNALIZED_STRING_TYPE:
case EXTERNAL_INTERNALIZED_STRING_TYPE:
case ONE_BYTE_INTERNALIZED_STRING_TYPE:
@ -735,7 +738,8 @@ void PrintFixedArrayWithHeader(std::ostream& os, FixedArray* array,
os << "\n";
}
void PrintWeakFixedArrayElements(std::ostream& os, WeakFixedArray* array) {
template <typename T>
void PrintWeakArrayElements(std::ostream& os, T* array) {
// Print in array notation for non-sparse arrays.
MaybeObject* previous_value = array->length() > 0 ? array->Get(0) : nullptr;
MaybeObject* value = nullptr;
@ -761,7 +765,15 @@ void PrintWeakFixedArrayElements(std::ostream& os, WeakFixedArray* array) {
void PrintWeakFixedArrayWithHeader(std::ostream& os, WeakFixedArray* array) {
array->PrintHeader(os, "WeakFixedArray");
os << "\n - length: " << array->length() << "\n";
PrintWeakFixedArrayElements(os, array);
PrintWeakArrayElements(os, array);
os << "\n";
}
void PrintWeakArrayListWithHeader(std::ostream& os, WeakArrayList* array) {
array->PrintHeader(os, "WeakArrayList");
os << "\n - capacity: " << array->capacity();
os << "\n - length: " << array->length() << "\n";
PrintWeakArrayElements(os, array);
os << "\n";
}
@ -795,6 +807,10 @@ void WeakFixedArray::WeakFixedArrayPrint(std::ostream& os) {
PrintWeakFixedArrayWithHeader(os, this);
}
void WeakArrayList::WeakArrayListPrint(std::ostream& os) {
PrintWeakArrayListWithHeader(os, this);
}
void TransitionArray::TransitionArrayPrint(std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "TransitionArray");
os << "\n - capacity: " << length();

View File

@ -3018,7 +3018,8 @@ VisitorId Map::GetVisitorId(Map* map) {
return kVisitFixedArray;
case WEAK_FIXED_ARRAY_TYPE:
return kVisitWeakFixedArray;
case WEAK_ARRAY_LIST_TYPE:
return kVisitWeakArray;
case FIXED_DOUBLE_ARRAY_TYPE:
return kVisitFixedDoubleArray;
@ -10362,6 +10363,35 @@ Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
return Handle<ArrayList>::cast(ret);
}
// static
Handle<WeakArrayList> WeakArrayList::Add(Handle<WeakArrayList> array,
Handle<HeapObject> obj1, Smi* obj2) {
int length = array->length();
array = EnsureSpace(array, length + 2);
// Check that GC didn't remove elements from the array.
DCHECK_EQ(array->length(), length);
array->Set(length, HeapObjectReference::Weak(*obj1));
array->Set(length + 1, MaybeObject::FromSmi(obj2));
array->set_length(length + 2);
return array;
}
bool WeakArrayList::IsFull() { return length() == capacity(); }
// static
Handle<WeakArrayList> WeakArrayList::EnsureSpace(Handle<WeakArrayList> array,
int length) {
int capacity = array->capacity();
if (capacity < length) {
Isolate* isolate = array->GetIsolate();
int new_capacity = length;
new_capacity = new_capacity + Max(new_capacity / 2, 2);
int grow_by = new_capacity - capacity;
array = isolate->factory()->CopyWeakArrayListAndGrow(array, grow_by);
}
return array;
}
Handle<RegExpMatchInfo> RegExpMatchInfo::ReserveCaptures(
Handle<RegExpMatchInfo> match_info, int capture_count) {
DCHECK_GE(match_info->length(), kLastMatchOverhead);

View File

@ -438,6 +438,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
V(STORE_HANDLER_TYPE) \
V(WEAK_CELL_TYPE) \
V(WEAK_FIXED_ARRAY_TYPE) \
V(WEAK_ARRAY_LIST_TYPE) \
\
V(JS_PROXY_TYPE) \
V(JS_GLOBAL_OBJECT_TYPE) \
@ -807,6 +808,7 @@ enum InstanceType : uint16_t {
STORE_HANDLER_TYPE,
WEAK_CELL_TYPE,
WEAK_FIXED_ARRAY_TYPE,
WEAK_ARRAY_LIST_TYPE,
// All the following types are subtypes of JSReceiver, which corresponds to
// objects in the JS sense. The first and the last type in this range are
@ -1145,7 +1147,8 @@ template <class C> inline bool Is(Object* obj);
V(WasmModuleObject) \
V(WasmTableObject) \
V(WeakCell) \
V(WeakFixedArray)
V(WeakFixedArray) \
V(WeakArrayList)
#define HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) \
V(Dictionary) \

View File

@ -18,6 +18,7 @@ TYPE_CHECKER(FixedArrayExact, FIXED_ARRAY_TYPE)
TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
TYPE_CHECKER(FixedArrayOfWeakCells, FIXED_ARRAY_TYPE)
TYPE_CHECKER(WeakFixedArray, WEAK_FIXED_ARRAY_TYPE)
TYPE_CHECKER(WeakArrayList, WEAK_ARRAY_LIST_TYPE)
CAST_ACCESSOR(ArrayList)
CAST_ACCESSOR(ByteArray)
@ -28,12 +29,17 @@ CAST_ACCESSOR(FixedTypedArrayBase)
CAST_ACCESSOR(TemplateList)
CAST_ACCESSOR(FixedArrayOfWeakCells)
CAST_ACCESSOR(WeakFixedArray)
CAST_ACCESSOR(WeakArrayList)
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
SMI_ACCESSORS(WeakArrayList, capacity, kCapacityOffset)
SYNCHRONIZED_SMI_ACCESSORS(WeakArrayList, capacity, kCapacityOffset)
SMI_ACCESSORS(WeakArrayList, length, kLengthOffset)
Object* FixedArrayBase::unchecked_synchronized_length() const {
return ACQUIRE_READ_FIELD(this, kLengthOffset);
}
@ -236,6 +242,23 @@ MaybeObject** WeakFixedArray::data_start() {
return HeapObject::RawMaybeWeakField(this, kHeaderSize);
}
MaybeObject* WeakArrayList::Get(int index) const {
SLOW_DCHECK(index >= 0 && index < this->capacity());
return RELAXED_READ_WEAK_FIELD(this, OffsetOfElementAt(index));
}
void WeakArrayList::Set(int index, MaybeObject* value, WriteBarrierMode mode) {
DCHECK_GE(index, 0);
DCHECK_LT(index, this->capacity());
int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(this, offset, value);
CONDITIONAL_WEAK_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
}
MaybeObject** WeakArrayList::data_start() {
return HeapObject::RawMaybeWeakField(this, kHeaderSize);
}
Object* FixedArrayOfWeakCells::Get(int index) const {
Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
if (raw->IsSmi()) return raw;

View File

@ -13,6 +13,8 @@
namespace v8 {
namespace internal {
class WeakArrayBodyDescriptor;
#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
V(BYTECODE_ARRAY_CONSTANT_POOL_SUB_TYPE) \
V(BYTECODE_ARRAY_HANDLER_TABLE_SUB_TYPE) \
@ -270,7 +272,7 @@ class WeakFixedArray : public HeapObject {
DECL_PRINTER(WeakFixedArray)
DECL_VERIFIER(WeakFixedArray)
class BodyDescriptor;
typedef WeakArrayBodyDescriptor BodyDescriptor;
typedef BodyDescriptor BodyDescriptorWeak;
static const int kLengthOffset = HeapObject::kHeaderSize;
@ -291,6 +293,65 @@ class WeakFixedArray : public HeapObject {
DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
};
// WeakArrayList is like a WeakFixedArray with static convenience methods for
// adding more elements. length() returns the number of elements in the list and
// capacity() returns the allocated size. The number of elements is stored at
// kLengthOffset and is updated with every insertion. The array grows
// dynamically with O(1) amortized insertion.
class WeakArrayList : public HeapObject {
public:
DECL_CAST(WeakArrayList)
DECL_VERIFIER(WeakArrayList)
DECL_PRINTER(WeakArrayList)
static Handle<WeakArrayList> Add(Handle<WeakArrayList> array,
Handle<HeapObject> obj1, Smi* obj2);
inline MaybeObject* Get(int index) const;
// Set the element at index to obj. The underlying array must be large enough.
// If you need to grow the WeakArrayList, use the static Add() methods
// instead.
inline void Set(int index, MaybeObject* value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
static constexpr int SizeForCapacity(int capacity) {
return kHeaderSize + capacity * kPointerSize;
}
// Gives access to raw memory which stores the array's data.
inline MaybeObject** data_start();
bool IsFull();
DECL_INT_ACCESSORS(capacity)
DECL_INT_ACCESSORS(length)
// Get and set the capacity using acquire loads and release stores.
inline int synchronized_capacity() const;
inline void synchronized_set_capacity(int value);
typedef WeakArrayBodyDescriptor BodyDescriptor;
typedef BodyDescriptor BodyDescriptorWeak;
static const int kCapacityOffset = HeapObject::kHeaderSize;
static const int kLengthOffset = kCapacityOffset + kPointerSize;
static const int kHeaderSize = kLengthOffset + kPointerSize;
static const int kMaxCapacity =
(FixedArray::kMaxSize - kHeaderSize) / kPointerSize;
private:
static int OffsetOfElementAt(int index) {
return kHeaderSize + index * kPointerSize;
}
static Handle<WeakArrayList> EnsureSpace(Handle<WeakArrayList> array,
int length);
DISALLOW_IMPLICIT_CONSTRUCTORS(WeakArrayList);
};
// Deprecated. Use WeakFixedArray instead.
class FixedArrayOfWeakCells : public FixedArray {
public:

View File

@ -57,7 +57,7 @@ namespace internal {
V(TransitionArray) \
V(WasmInstanceObject) \
V(WeakCell) \
V(WeakFixedArray)
V(WeakArray)
// For data objects, JS objects and structs along with generic visitor which
// can visit object of any size we provide visitors specialized by

View File

@ -19,6 +19,11 @@ bool MaybeObject::ToSmi(Smi** value) {
return false;
}
Smi* MaybeObject::ToSmi() {
DCHECK(HAS_SMI_TAG(this));
return Smi::cast(reinterpret_cast<Object*>(this));
}
bool MaybeObject::IsStrongOrWeakHeapObject() {
if (IsSmi() || IsClearedWeakHeapObject()) {
return false;

View File

@ -21,6 +21,7 @@ class MaybeObject {
public:
bool IsSmi() const { return HAS_SMI_TAG(this); }
inline bool ToSmi(Smi** value);
inline Smi* ToSmi();
bool IsClearedWeakHeapObject() {
return ::v8::internal::IsClearedWeakHeapObject(this);

View File

@ -885,7 +885,11 @@ bool V8HeapExplorer::ExtractReferencesPass1(int entry, HeapObject* obj) {
} else if (obj->IsFeedbackVector()) {
ExtractFeedbackVectorReferences(entry, FeedbackVector::cast(obj));
} else if (obj->IsWeakFixedArray()) {
ExtractWeakFixedArrayReferences(entry, WeakFixedArray::cast(obj));
ExtractWeakArrayReferences(WeakFixedArray::kHeaderSize, entry,
WeakFixedArray::cast(obj));
} else if (obj->IsWeakArrayList()) {
ExtractWeakArrayReferences(WeakArrayList::kHeaderSize, entry,
WeakArrayList::cast(obj));
}
return true;
}
@ -1398,14 +1402,15 @@ void V8HeapExplorer::ExtractFeedbackVectorReferences(
}
}
void V8HeapExplorer::ExtractWeakFixedArrayReferences(int entry,
WeakFixedArray* array) {
template <typename T>
void V8HeapExplorer::ExtractWeakArrayReferences(int header_size, int entry,
T* array) {
for (int i = 0; i < array->length(); ++i) {
MaybeObject* object = array->Get(i);
HeapObject* heap_object;
if (object->ToWeakHeapObject(&heap_object)) {
SetWeakReference(array, entry, i, heap_object,
WeakFixedArray::kHeaderSize + i * kPointerSize);
header_size + i * kPointerSize);
}
}
}

View File

@ -396,7 +396,8 @@ class V8HeapExplorer : public HeapEntriesAllocator {
void ExtractFixedArrayReferences(int entry, FixedArray* array);
void ExtractFeedbackVectorReferences(int entry,
FeedbackVector* feedback_vector);
void ExtractWeakFixedArrayReferences(int entry, WeakFixedArray* array);
template <typename T>
void ExtractWeakArrayReferences(int header_size, int entry, T* array);
void ExtractPropertyReferences(JSObject* js_obj, int entry);
void ExtractAccessorPairProperty(JSObject* js_obj, int entry, Name* key,
Object* callback_obj, int field_offset = -1);

View File

@ -4618,17 +4618,18 @@ TEST(Regress3877) {
CHECK(weak_prototype->cleared());
}
Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) {
HandleScope inner_scope(isolate);
Handle<Map> map = Map::Create(isolate, 1);
v8::Local<v8::Value> result =
CompileRun("(function () { return {x : 10}; })();");
Handle<JSReceiver> proto =
v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result));
Map::SetPrototype(map, proto);
heap->AddRetainedMap(map);
return inner_scope.CloseAndEscape(Map::WeakCellForMap(map));
Handle<WeakFixedArray> AddRetainedMap(Isolate* isolate, Heap* heap) {
HandleScope inner_scope(isolate);
Handle<Map> map = Map::Create(isolate, 1);
v8::Local<v8::Value> result =
CompileRun("(function () { return {x : 10}; })();");
Handle<JSReceiver> proto =
v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result));
Map::SetPrototype(map, proto);
heap->AddRetainedMap(map);
Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(1);
array->Set(0, HeapObjectReference::Weak(*map));
return inner_scope.CloseAndEscape(array);
}
@ -4636,16 +4637,16 @@ void CheckMapRetainingFor(int n) {
FLAG_retain_maps_for_n_gc = n;
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
Handle<WeakCell> weak_cell = AddRetainedMap(isolate, heap);
CHECK(!weak_cell->cleared());
Handle<WeakFixedArray> array_with_map = AddRetainedMap(isolate, heap);
CHECK(array_with_map->Get(0)->IsWeakHeapObject());
for (int i = 0; i < n; i++) {
heap::SimulateIncrementalMarking(heap);
CcTest::CollectGarbage(OLD_SPACE);
}
CHECK(!weak_cell->cleared());
CHECK(array_with_map->Get(0)->IsWeakHeapObject());
heap::SimulateIncrementalMarking(heap);
CcTest::CollectGarbage(OLD_SPACE);
CHECK(weak_cell->cleared());
CHECK(array_with_map->Get(0)->IsClearedWeakHeapObject());
}

View File

@ -425,6 +425,102 @@ TEST(WeakArraysBasic) {
CHECK(array->Get(3)->IsClearedWeakHeapObject());
}
TEST(WeakArrayListBasic) {
ManualGCScope manual_gc_scope;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope outer_scope(isolate);
Handle<WeakArrayList> array(heap->empty_weak_array_list());
CHECK(array->IsWeakArrayList());
CHECK(!array->IsFixedArray());
CHECK(!array->IsWeakFixedArray());
CHECK_EQ(array->length(), 0);
Handle<FixedArray> index2 = factory->NewFixedArray(1);
index2->set(0, Smi::FromInt(2017));
Handle<HeapObject> saved;
{
HandleScope inner_scope(isolate);
Handle<FixedArray> index0 = factory->NewFixedArray(1);
index0->set(0, Smi::FromInt(2016));
Handle<FixedArray> index4 = factory->NewFixedArray(1);
index4->set(0, Smi::FromInt(2018));
Handle<FixedArray> index6 = factory->NewFixedArray(1);
index6->set(0, Smi::FromInt(2019));
array = WeakArrayList::Add(array, index0, Smi::FromInt(1));
CHECK_EQ(array->length(), 2);
array = WeakArrayList::Add(array, index2, Smi::FromInt(3));
CHECK_EQ(array->length(), 4);
array = WeakArrayList::Add(array, index4, Smi::FromInt(5));
CHECK_EQ(array->length(), 6);
array = WeakArrayList::Add(array, index6, Smi::FromInt(7));
CHECK_EQ(array->length(), 8);
CHECK(heap->InNewSpace(*array));
CHECK_EQ(array->Get(0), HeapObjectReference::Weak(*index0));
CHECK_EQ(Smi::ToInt(array->Get(1)->ToSmi()), 1);
CHECK_EQ(array->Get(2), HeapObjectReference::Weak(*index2));
CHECK_EQ(Smi::ToInt(array->Get(3)->ToSmi()), 3);
CHECK_EQ(array->Get(4), HeapObjectReference::Weak(*index4));
CHECK_EQ(Smi::ToInt(array->Get(5)->ToSmi()), 5);
CHECK_EQ(array->Get(6), HeapObjectReference::Weak(*index6));
array = inner_scope.CloseAndEscape(array);
} // inner_scope goes out of scope.
// The references are only cleared by the mark-compact (scavenger treats weak
// references as strong). Thus we need to GC until the array reaches old
// space.
// TODO(marja): update this when/if we do handle weak references in the new
// space.
CcTest::CollectGarbage(NEW_SPACE);
HeapObject* heap_object;
CHECK_EQ(array->length(), 8);
CHECK(array->Get(0)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2016);
CHECK_EQ(Smi::ToInt(array->Get(1)->ToSmi()), 1);
CHECK(array->Get(2)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2017);
CHECK_EQ(Smi::ToInt(array->Get(3)->ToSmi()), 3);
CHECK(array->Get(4)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2018);
CHECK_EQ(Smi::ToInt(array->Get(5)->ToSmi()), 5);
CHECK(array->Get(6)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2019);
CHECK_EQ(Smi::ToInt(array->Get(7)->ToSmi()), 7);
CcTest::CollectAllGarbage();
CHECK(heap->InOldSpace(*array));
CHECK_EQ(array->length(), 8);
CHECK(array->Get(0)->IsClearedWeakHeapObject());
CHECK_EQ(Smi::ToInt(array->Get(1)->ToSmi()), 1);
CHECK(array->Get(2)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2017);
CHECK_EQ(Smi::ToInt(array->Get(3)->ToSmi()), 3);
CHECK(array->Get(4)->IsClearedWeakHeapObject());
CHECK_EQ(Smi::ToInt(array->Get(5)->ToSmi()), 5);
CHECK(array->Get(6)->IsClearedWeakHeapObject());
CHECK_EQ(Smi::ToInt(array->Get(7)->ToSmi()), 7);
}
} // namespace heap
} // namespace internal
} // namespace v8

View File

@ -113,6 +113,7 @@ INSTANCE_TYPES = {
209: "STORE_HANDLER_TYPE",
210: "WEAK_CELL_TYPE",
211: "WEAK_FIXED_ARRAY_TYPE",
212: "WEAK_ARRAY_LIST_TYPE",
1024: "JS_PROXY_TYPE",
1025: "JS_GLOBAL_OBJECT_TYPE",
1026: "JS_GLOBAL_PROXY_TYPE",
@ -228,68 +229,69 @@ KNOWN_MAPS = {
("MAP_SPACE", 0x03909): (208, "SmallOrderedHashSetMap"),
("MAP_SPACE", 0x03961): (186, "StringTableMap"),
("MAP_SPACE", 0x039b9): (211, "WeakFixedArrayMap"),
("MAP_SPACE", 0x03a11): (106, "NativeSourceStringMap"),
("MAP_SPACE", 0x03a69): (64, "StringMap"),
("MAP_SPACE", 0x03ac1): (73, "ConsOneByteStringMap"),
("MAP_SPACE", 0x03b19): (65, "ConsStringMap"),
("MAP_SPACE", 0x03b71): (77, "ThinOneByteStringMap"),
("MAP_SPACE", 0x03bc9): (69, "ThinStringMap"),
("MAP_SPACE", 0x03c21): (67, "SlicedStringMap"),
("MAP_SPACE", 0x03c79): (75, "SlicedOneByteStringMap"),
("MAP_SPACE", 0x03cd1): (66, "ExternalStringMap"),
("MAP_SPACE", 0x03d29): (82, "ExternalStringWithOneByteDataMap"),
("MAP_SPACE", 0x03d81): (74, "ExternalOneByteStringMap"),
("MAP_SPACE", 0x03dd9): (98, "ShortExternalStringMap"),
("MAP_SPACE", 0x03e31): (114, "ShortExternalStringWithOneByteDataMap"),
("MAP_SPACE", 0x03e89): (0, "InternalizedStringMap"),
("MAP_SPACE", 0x03ee1): (2, "ExternalInternalizedStringMap"),
("MAP_SPACE", 0x03f39): (18, "ExternalInternalizedStringWithOneByteDataMap"),
("MAP_SPACE", 0x03f91): (10, "ExternalOneByteInternalizedStringMap"),
("MAP_SPACE", 0x03fe9): (34, "ShortExternalInternalizedStringMap"),
("MAP_SPACE", 0x04041): (50, "ShortExternalInternalizedStringWithOneByteDataMap"),
("MAP_SPACE", 0x04099): (42, "ShortExternalOneByteInternalizedStringMap"),
("MAP_SPACE", 0x040f1): (106, "ShortExternalOneByteStringMap"),
("MAP_SPACE", 0x04149): (140, "FixedUint8ArrayMap"),
("MAP_SPACE", 0x041a1): (139, "FixedInt8ArrayMap"),
("MAP_SPACE", 0x041f9): (142, "FixedUint16ArrayMap"),
("MAP_SPACE", 0x04251): (141, "FixedInt16ArrayMap"),
("MAP_SPACE", 0x042a9): (144, "FixedUint32ArrayMap"),
("MAP_SPACE", 0x04301): (143, "FixedInt32ArrayMap"),
("MAP_SPACE", 0x04359): (145, "FixedFloat32ArrayMap"),
("MAP_SPACE", 0x043b1): (146, "FixedFloat64ArrayMap"),
("MAP_SPACE", 0x04409): (147, "FixedUint8ClampedArrayMap"),
("MAP_SPACE", 0x04461): (149, "FixedBigUint64ArrayMap"),
("MAP_SPACE", 0x044b9): (148, "FixedBigInt64ArrayMap"),
("MAP_SPACE", 0x04511): (173, "Tuple2Map"),
("MAP_SPACE", 0x04569): (171, "ScriptMap"),
("MAP_SPACE", 0x045c1): (163, "InterceptorInfoMap"),
("MAP_SPACE", 0x04619): (154, "AccessorInfoMap"),
("MAP_SPACE", 0x04671): (153, "AccessCheckInfoMap"),
("MAP_SPACE", 0x046c9): (155, "AccessorPairMap"),
("MAP_SPACE", 0x04721): (156, "AliasedArgumentsEntryMap"),
("MAP_SPACE", 0x04779): (157, "AllocationMementoMap"),
("MAP_SPACE", 0x047d1): (158, "AllocationSiteMap"),
("MAP_SPACE", 0x04829): (159, "AsyncGeneratorRequestMap"),
("MAP_SPACE", 0x04881): (160, "ContextExtensionMap"),
("MAP_SPACE", 0x048d9): (161, "DebugInfoMap"),
("MAP_SPACE", 0x04931): (162, "FunctionTemplateInfoMap"),
("MAP_SPACE", 0x04989): (164, "InterpreterDataMap"),
("MAP_SPACE", 0x049e1): (165, "ModuleInfoEntryMap"),
("MAP_SPACE", 0x04a39): (166, "ModuleMap"),
("MAP_SPACE", 0x04a91): (167, "ObjectTemplateInfoMap"),
("MAP_SPACE", 0x04ae9): (168, "PromiseCapabilityMap"),
("MAP_SPACE", 0x04b41): (169, "PromiseReactionMap"),
("MAP_SPACE", 0x04b99): (170, "PrototypeInfoMap"),
("MAP_SPACE", 0x04bf1): (172, "StackFrameInfoMap"),
("MAP_SPACE", 0x04c49): (174, "Tuple3Map"),
("MAP_SPACE", 0x04ca1): (175, "WasmCompiledModuleMap"),
("MAP_SPACE", 0x04cf9): (176, "WasmDebugInfoMap"),
("MAP_SPACE", 0x04d51): (177, "WasmSharedModuleDataMap"),
("MAP_SPACE", 0x04da9): (178, "CallableTaskMap"),
("MAP_SPACE", 0x04e01): (179, "CallbackTaskMap"),
("MAP_SPACE", 0x04e59): (180, "PromiseFulfillReactionJobTaskMap"),
("MAP_SPACE", 0x04eb1): (181, "PromiseRejectReactionJobTaskMap"),
("MAP_SPACE", 0x04f09): (182, "PromiseResolveThenableJobTaskMap"),
("MAP_SPACE", 0x03a11): (212, "WeakArrayListMap"),
("MAP_SPACE", 0x03a69): (106, "NativeSourceStringMap"),
("MAP_SPACE", 0x03ac1): (64, "StringMap"),
("MAP_SPACE", 0x03b19): (73, "ConsOneByteStringMap"),
("MAP_SPACE", 0x03b71): (65, "ConsStringMap"),
("MAP_SPACE", 0x03bc9): (77, "ThinOneByteStringMap"),
("MAP_SPACE", 0x03c21): (69, "ThinStringMap"),
("MAP_SPACE", 0x03c79): (67, "SlicedStringMap"),
("MAP_SPACE", 0x03cd1): (75, "SlicedOneByteStringMap"),
("MAP_SPACE", 0x03d29): (66, "ExternalStringMap"),
("MAP_SPACE", 0x03d81): (82, "ExternalStringWithOneByteDataMap"),
("MAP_SPACE", 0x03dd9): (74, "ExternalOneByteStringMap"),
("MAP_SPACE", 0x03e31): (98, "ShortExternalStringMap"),
("MAP_SPACE", 0x03e89): (114, "ShortExternalStringWithOneByteDataMap"),
("MAP_SPACE", 0x03ee1): (0, "InternalizedStringMap"),
("MAP_SPACE", 0x03f39): (2, "ExternalInternalizedStringMap"),
("MAP_SPACE", 0x03f91): (18, "ExternalInternalizedStringWithOneByteDataMap"),
("MAP_SPACE", 0x03fe9): (10, "ExternalOneByteInternalizedStringMap"),
("MAP_SPACE", 0x04041): (34, "ShortExternalInternalizedStringMap"),
("MAP_SPACE", 0x04099): (50, "ShortExternalInternalizedStringWithOneByteDataMap"),
("MAP_SPACE", 0x040f1): (42, "ShortExternalOneByteInternalizedStringMap"),
("MAP_SPACE", 0x04149): (106, "ShortExternalOneByteStringMap"),
("MAP_SPACE", 0x041a1): (140, "FixedUint8ArrayMap"),
("MAP_SPACE", 0x041f9): (139, "FixedInt8ArrayMap"),
("MAP_SPACE", 0x04251): (142, "FixedUint16ArrayMap"),
("MAP_SPACE", 0x042a9): (141, "FixedInt16ArrayMap"),
("MAP_SPACE", 0x04301): (144, "FixedUint32ArrayMap"),
("MAP_SPACE", 0x04359): (143, "FixedInt32ArrayMap"),
("MAP_SPACE", 0x043b1): (145, "FixedFloat32ArrayMap"),
("MAP_SPACE", 0x04409): (146, "FixedFloat64ArrayMap"),
("MAP_SPACE", 0x04461): (147, "FixedUint8ClampedArrayMap"),
("MAP_SPACE", 0x044b9): (149, "FixedBigUint64ArrayMap"),
("MAP_SPACE", 0x04511): (148, "FixedBigInt64ArrayMap"),
("MAP_SPACE", 0x04569): (173, "Tuple2Map"),
("MAP_SPACE", 0x045c1): (171, "ScriptMap"),
("MAP_SPACE", 0x04619): (163, "InterceptorInfoMap"),
("MAP_SPACE", 0x04671): (154, "AccessorInfoMap"),
("MAP_SPACE", 0x046c9): (153, "AccessCheckInfoMap"),
("MAP_SPACE", 0x04721): (155, "AccessorPairMap"),
("MAP_SPACE", 0x04779): (156, "AliasedArgumentsEntryMap"),
("MAP_SPACE", 0x047d1): (157, "AllocationMementoMap"),
("MAP_SPACE", 0x04829): (158, "AllocationSiteMap"),
("MAP_SPACE", 0x04881): (159, "AsyncGeneratorRequestMap"),
("MAP_SPACE", 0x048d9): (160, "ContextExtensionMap"),
("MAP_SPACE", 0x04931): (161, "DebugInfoMap"),
("MAP_SPACE", 0x04989): (162, "FunctionTemplateInfoMap"),
("MAP_SPACE", 0x049e1): (164, "InterpreterDataMap"),
("MAP_SPACE", 0x04a39): (165, "ModuleInfoEntryMap"),
("MAP_SPACE", 0x04a91): (166, "ModuleMap"),
("MAP_SPACE", 0x04ae9): (167, "ObjectTemplateInfoMap"),
("MAP_SPACE", 0x04b41): (168, "PromiseCapabilityMap"),
("MAP_SPACE", 0x04b99): (169, "PromiseReactionMap"),
("MAP_SPACE", 0x04bf1): (170, "PrototypeInfoMap"),
("MAP_SPACE", 0x04c49): (172, "StackFrameInfoMap"),
("MAP_SPACE", 0x04ca1): (174, "Tuple3Map"),
("MAP_SPACE", 0x04cf9): (175, "WasmCompiledModuleMap"),
("MAP_SPACE", 0x04d51): (176, "WasmDebugInfoMap"),
("MAP_SPACE", 0x04da9): (177, "WasmSharedModuleDataMap"),
("MAP_SPACE", 0x04e01): (178, "CallableTaskMap"),
("MAP_SPACE", 0x04e59): (179, "CallbackTaskMap"),
("MAP_SPACE", 0x04eb1): (180, "PromiseFulfillReactionJobTaskMap"),
("MAP_SPACE", 0x04f09): (181, "PromiseRejectReactionJobTaskMap"),
("MAP_SPACE", 0x04f61): (182, "PromiseResolveThenableJobTaskMap"),
}
# List of known V8 objects.
@ -329,15 +331,15 @@ KNOWN_OBJECTS = {
("OLD_SPACE", 0x02919): "EmptyOrderedHashSet",
("OLD_SPACE", 0x02951): "EmptyPropertyCell",
("OLD_SPACE", 0x02979): "EmptyWeakCell",
("OLD_SPACE", 0x029e9): "NoElementsProtector",
("OLD_SPACE", 0x02a11): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x02a21): "SpeciesProtector",
("OLD_SPACE", 0x02a49): "StringLengthProtector",
("OLD_SPACE", 0x02a59): "ArrayIteratorProtector",
("OLD_SPACE", 0x02a81): "ArrayBufferNeuteringProtector",
("OLD_SPACE", 0x02b09): "InfinityValue",
("OLD_SPACE", 0x02b19): "MinusZeroValue",
("OLD_SPACE", 0x02b29): "MinusInfinityValue",
("OLD_SPACE", 0x02a01): "NoElementsProtector",
("OLD_SPACE", 0x02a29): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x02a39): "SpeciesProtector",
("OLD_SPACE", 0x02a61): "StringLengthProtector",
("OLD_SPACE", 0x02a71): "ArrayIteratorProtector",
("OLD_SPACE", 0x02a99): "ArrayBufferNeuteringProtector",
("OLD_SPACE", 0x02b21): "InfinityValue",
("OLD_SPACE", 0x02b31): "MinusZeroValue",
("OLD_SPACE", 0x02b41): "MinusInfinityValue",
}
# List of known V8 Frame Markers.