[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:
parent
2e59ff8c45
commit
d3a2819ee9
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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:
|
||||
|
@ -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());
|
||||
|
@ -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(
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user