[in-place weak refs] Add WeakFixedArray (an array of in-place weak references).

Not used yet apart from tests.

BUG=v8:7308

Change-Id: Ibbe12597007cba123236c9fab85c524df3d5dd4a
Reviewed-on: https://chromium-review.googlesource.com/955427
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51876}
This commit is contained in:
Marja Hölttä 2018-03-12 11:26:53 +01:00 committed by Commit Bot
parent 8f1cdc722b
commit b0dc290a9a
22 changed files with 388 additions and 85 deletions

View File

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

View File

@ -203,6 +203,16 @@ Handle<FixedArray> Factory::NewFixedArray(int length, PretenureFlag pretenure) {
FixedArray);
}
Handle<WeakFixedArray> Factory::NewWeakFixedArray(int length,
PretenureFlag pretenure) {
DCHECK_LE(0, length);
if (length == 0) return empty_weak_fixed_array();
CALL_HEAP_FUNCTION(
isolate(), isolate()->heap()->AllocateWeakFixedArray(length, pretenure),
WeakFixedArray);
}
MaybeHandle<FixedArray> Factory::TryNewFixedArray(int length,
PretenureFlag pretenure) {
DCHECK_LE(0, length);

View File

@ -96,6 +96,12 @@ class V8_EXPORT_PRIVATE Factory final {
// Allocates a fixed array initialized with undefined values.
Handle<FixedArray> NewFixedArray(int length,
PretenureFlag pretenure = NOT_TENURED);
// Allocates a fixed array which may contain in-place weak references. The
// array is initialized with undefined values
Handle<WeakFixedArray> NewWeakFixedArray(
int length, PretenureFlag pretenure = NOT_TENURED);
Handle<PropertyArray> NewPropertyArray(int length,
PretenureFlag pretenure = NOT_TENURED);
// Tries allocating a fixed array initialized with undefined values.

View File

@ -247,6 +247,42 @@ AllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
pretenure, undefined_value());
}
AllocationResult Heap::AllocateWeakFixedArray(int length,
PretenureFlag pretenure) {
// Zero-length case must be handled outside, where the knowledge about
// the map is.
DCHECK_LT(0, length);
HeapObject* result = nullptr;
{
AllocationResult allocation = AllocateRawWeakFixedArray(length, pretenure);
if (!allocation.To(&result)) return allocation;
}
DCHECK(RootIsImmortalImmovable(Heap::kWeakFixedArrayMapRootIndex));
Map* map = Map::cast(root(Heap::kWeakFixedArrayMapRootIndex));
result->set_map_after_allocation(map, SKIP_WRITE_BARRIER);
WeakFixedArray* array = WeakFixedArray::cast(result);
array->set_length(length);
MemsetPointer(array->data_start(),
HeapObjectReference::Strong(undefined_value()), length);
return array;
}
AllocationResult Heap::AllocateRawFixedArray(int length,
PretenureFlag pretenure) {
if (length < 0 || length > FixedArray::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
}
return AllocateRawArray(FixedArray::SizeFor(length), pretenure);
}
AllocationResult Heap::AllocateRawWeakFixedArray(int length,
PretenureFlag pretenure) {
if (length < 0 || length > WeakFixedArray::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
}
return AllocateRawArray(WeakFixedArray::SizeFor(length), pretenure);
}
AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationSpace space,
AllocationAlignment alignment) {
DCHECK(AllowHandleAllocation::IsAllowed());

View File

@ -3763,6 +3763,18 @@ AllocationResult Heap::AllocateEmptyFixedArray() {
return result;
}
AllocationResult Heap::AllocateEmptyWeakFixedArray() {
int size = WeakFixedArray::SizeFor(0);
HeapObject* result = nullptr;
{
AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
if (!allocation.To(&result)) return allocation;
}
result->set_map_after_allocation(weak_fixed_array_map(), SKIP_WRITE_BARRIER);
WeakFixedArray::cast(result)->set_length(0);
return result;
}
AllocationResult Heap::AllocateEmptyScopeInfo() {
int size = FixedArray::SizeFor(0);
HeapObject* result = nullptr;
@ -3975,12 +3987,7 @@ AllocationResult Heap::CopyFeedbackVector(FeedbackVector* src) {
return result;
}
AllocationResult Heap::AllocateRawFixedArray(int length,
PretenureFlag pretenure) {
if (length < 0 || length > FixedArray::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
}
int size = FixedArray::SizeFor(length);
AllocationResult Heap::AllocateRawArray(int size, PretenureFlag pretenure) {
AllocationSpace space = SelectSpace(pretenure);
AllocationResult result = AllocateRaw(size, space);

View File

@ -133,6 +133,7 @@ using v8::MemoryPressureLevel;
V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \
V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \
V(Map, string_table_map, StringTableMap) \
V(Map, weak_fixed_array_map, WeakFixedArrayMap) \
V(Map, weak_hash_table_map, WeakHashTableMap) \
/* String maps */ \
V(Map, native_source_string_map, NativeSourceStringMap) \
@ -217,6 +218,7 @@ using v8::MemoryPressureLevel;
V(WeakCell, empty_weak_cell, EmptyWeakCell) \
V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
V(WeakFixedArray, empty_weak_fixed_array, EmptyWeakFixedArray) \
/* Protectors */ \
V(Cell, array_constructor_protector, ArrayConstructorProtector) \
V(PropertyCell, no_elements_protector, NoElementsProtector) \
@ -403,6 +405,7 @@ using v8::MemoryPressureLevel;
V(UninitializedMap) \
V(UninitializedValue) \
V(WeakCellMap) \
V(WeakFixedArrayMap) \
V(WeakHashTableMap) \
V(WithContextMap) \
V(empty_string) \
@ -2159,6 +2162,19 @@ class Heap {
MUST_USE_RESULT inline AllocationResult AllocateFixedArray(
int length, PretenureFlag pretenure = NOT_TENURED);
// Allocates an array allowing in-place weak references, initialized with
// undefined values
MUST_USE_RESULT inline AllocationResult AllocateWeakFixedArray(
int length, PretenureFlag pretenure = NOT_TENURED);
// Allocate memory for an uninitialized FixedArray.
MUST_USE_RESULT inline AllocationResult AllocateRawFixedArray(
int length, PretenureFlag pretenure);
// Allocate memory for an uninitialized WeakFixedArray.
MUST_USE_RESULT inline AllocationResult AllocateRawWeakFixedArray(
int length, PretenureFlag pretenure);
// Allocates a property array initialized with undefined values
MUST_USE_RESULT AllocationResult
AllocatePropertyArray(int length, PretenureFlag pretenure = NOT_TENURED);
@ -2199,9 +2215,9 @@ class Heap {
MUST_USE_RESULT AllocationResult
AllocateFillerObject(int size, bool double_align, AllocationSpace space);
// Allocate an uninitialized fixed array.
MUST_USE_RESULT AllocationResult
AllocateRawFixedArray(int length, PretenureFlag pretenure);
// Allocate memory for an uninitialized array (e.g., a FixedArray or similar).
MUST_USE_RESULT AllocationResult AllocateRawArray(int size,
PretenureFlag pretenure);
// Allocate an uninitialized fixed double array.
MUST_USE_RESULT AllocationResult
@ -2313,6 +2329,9 @@ class Heap {
// Allocate empty fixed array like objects.
MUST_USE_RESULT AllocationResult AllocateEmptyFixedArray();
MUST_USE_RESULT AllocationResult AllocateEmptyWeakFixedArray();
MUST_USE_RESULT AllocationResult AllocateEmptyScopeInfo();
MUST_USE_RESULT AllocationResult AllocateEmptyBoilerplateDescription();

View File

@ -3033,7 +3033,9 @@ class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
void VisitPointers(HeapObject* host, MaybeObject** start,
MaybeObject** end) final {
UNREACHABLE();
for (MaybeObject** p = start; p < end; p++) {
UpdateSlotInternal(p);
}
}
void VisitRootPointer(Root root, const char* description,

View File

@ -55,7 +55,8 @@ class JSWeakCollection;
V(Symbol) \
V(ThinString) \
V(TransitionArray) \
V(WeakCell)
V(WeakCell) \
V(WeakFixedArray)
// 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

View File

@ -113,6 +113,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(FIXED_ARRAY_TYPE, kVariableSizeSentinel,
fixed_cow_array)
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
@ -134,6 +136,12 @@ bool Heap::CreateInitialMaps() {
}
set_empty_fixed_array(FixedArray::cast(obj));
{
AllocationResult allocation = AllocateEmptyWeakFixedArray();
if (!allocation.To(&obj)) return false;
}
set_empty_weak_fixed_array(WeakFixedArray::cast(obj));
{
AllocationResult allocation = Allocate(null_map(), OLD_SPACE);
if (!allocation.To(&obj)) return false;
@ -192,6 +200,7 @@ bool Heap::CreateInitialMaps() {
// Fix the instance_descriptors for the existing maps.
FinalizePartialMap(this, meta_map());
FinalizePartialMap(this, fixed_array_map());
FinalizePartialMap(this, weak_fixed_array_map());
FinalizePartialMap(this, fixed_cow_array_map());
FinalizePartialMap(this, descriptor_array_map());
FinalizePartialMap(this, undefined_map());

View File

@ -69,6 +69,13 @@ void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset,
v->VisitPointer(obj, HeapObject::RawField(obj, offset));
}
template <typename ObjectVisitor>
DISABLE_CFI_PERF void BodyDescriptorBase::IterateMaybeWeakPointers(
HeapObject* obj, int start_offset, int end_offset, ObjectVisitor* v) {
v->VisitPointers(obj, HeapObject::RawMaybeWeakField(obj, start_offset),
HeapObject::RawMaybeWeakField(obj, end_offset));
}
template <typename ObjectVisitor>
void BodyDescriptorBase::IterateMaybeWeakPointer(HeapObject* obj, int offset,
ObjectVisitor* v) {
@ -268,6 +275,23 @@ class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
}
};
class WeakFixedArray::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(HeapObject* obj, int offset) {
return offset >= kHeaderSize;
}
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
IterateMaybeWeakPointers(obj, kHeaderSize, object_size, v);
}
static inline int SizeOf(Map* map, HeapObject* object) {
return object->SizeFromMap(map);
}
};
class FeedbackMetadata::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
@ -472,6 +496,8 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
case HASH_TABLE_TYPE:
case SCOPE_INFO_TYPE:
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3);
case WEAK_FIXED_ARRAY_TYPE:
return Op::template apply<WeakFixedArray::BodyDescriptor>(p1, p2, p3);
case FIXED_DOUBLE_ARRAY_TYPE:
return ReturnType();
case FEEDBACK_METADATA_TYPE:

View File

@ -36,6 +36,10 @@ class BodyDescriptorBase BASE_EMBEDDED {
static inline void IteratePointer(HeapObject* obj, int offset,
ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateMaybeWeakPointers(HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateMaybeWeakPointer(HeapObject* obj, int offset,
ObjectVisitor* v);

View File

@ -126,6 +126,9 @@ void HeapObject::HeapObjectVerify() {
case SCOPE_INFO_TYPE:
FixedArray::cast(this)->FixedArrayVerify();
break;
case WEAK_FIXED_ARRAY_TYPE:
WeakFixedArray::cast(this)->WeakFixedArrayVerify();
break;
case FIXED_DOUBLE_ARRAY_TYPE:
FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
break;
@ -529,6 +532,12 @@ void FixedArray::FixedArrayVerify() {
}
}
void WeakFixedArray::WeakFixedArrayVerify() {
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

@ -2234,6 +2234,10 @@ int HeapObject::SizeFromMap(Map* map) const {
reinterpret_cast<const FeedbackMetadata*>(this)
->synchronized_slot_count());
}
if (instance_type == WEAK_FIXED_ARRAY_TYPE) {
return WeakFixedArray::SizeFor(
reinterpret_cast<const WeakFixedArray*>(this)->synchronized_length());
}
if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
return reinterpret_cast<const FixedTypedArrayBase*>(this)->TypedArraySize(

View File

@ -2984,6 +2984,9 @@ VisitorId Map::GetVisitorId(Map* map) {
case SCOPE_INFO_TYPE:
return kVisitFixedArray;
case WEAK_FIXED_ARRAY_TYPE:
return kVisitWeakFixedArray;
case FIXED_DOUBLE_ARRAY_TYPE:
return kVisitFixedDoubleArray;

View File

@ -413,6 +413,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
V(SMALL_ORDERED_HASH_SET_TYPE) \
V(STORE_HANDLER_TYPE) \
V(WEAK_CELL_TYPE) \
V(WEAK_FIXED_ARRAY_TYPE) \
\
V(JS_PROXY_TYPE) \
V(JS_GLOBAL_OBJECT_TYPE) \
@ -767,6 +768,7 @@ enum InstanceType : uint16_t {
SMALL_ORDERED_HASH_SET_TYPE,
STORE_HANDLER_TYPE,
WEAK_CELL_TYPE,
WEAK_FIXED_ARRAY_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
@ -985,6 +987,7 @@ template <class C> inline bool Is(Object* obj);
V(FixedArray) \
V(FixedArrayBase) \
V(FixedArrayExact) \
V(FixedArrayOfWeakCells) \
V(FixedBigInt64Array) \
V(FixedBigUint64Array) \
V(FixedDoubleArray) \
@ -1097,7 +1100,7 @@ template <class C> inline bool Is(Object* obj);
V(WasmModuleObject) \
V(WasmTableObject) \
V(WeakCell) \
V(FixedArrayOfWeakCells) \
V(WeakFixedArray) \
V(WeakHashTable)
#define HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) \

View File

@ -17,6 +17,7 @@ TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
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)
CAST_ACCESSOR(ArrayList)
CAST_ACCESSOR(ByteArray)
@ -26,9 +27,12 @@ CAST_ACCESSOR(FixedDoubleArray)
CAST_ACCESSOR(FixedTypedArrayBase)
CAST_ACCESSOR(TemplateList)
CAST_ACCESSOR(FixedArrayOfWeakCells)
CAST_ACCESSOR(WeakFixedArray)
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
Object* FixedArrayBase::unchecked_synchronized_length() const {
return ACQUIRE_READ_FIELD(this, kLengthOffset);
@ -142,7 +146,7 @@ void FixedArray::FillWithHoles(int from, int to) {
}
Object** FixedArray::data_start() {
return HeapObject::RawField(this, kHeaderSize);
return HeapObject::RawField(this, OffsetOfElementAt(0));
}
Object** FixedArray::RawFieldOfElementAt(int index) {
@ -215,6 +219,23 @@ void FixedDoubleArray::FillWithHoles(int from, int to) {
}
}
MaybeObject* WeakFixedArray::Get(int index) const {
SLOW_DCHECK(index >= 0 && index < this->length());
return RELAXED_READ_WEAK_FIELD(this, OffsetOfElementAt(index));
}
void WeakFixedArray::Set(int index, MaybeObject* value) {
DCHECK_GE(index, 0);
DCHECK_LT(index, length());
int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(this, offset, value);
WEAK_WRITE_BARRIER(GetHeap(), this, offset, value);
}
MaybeObject** WeakFixedArray::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

@ -243,6 +243,54 @@ class FixedDoubleArray : public FixedArrayBase {
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
};
// WeakFixedArray describes fixed-sized arrays with element type
// MaybeObject*.
class WeakFixedArray : public HeapObject {
public:
DECL_CAST(WeakFixedArray)
inline MaybeObject* Get(int index) const;
// Setter that uses write barrier.
inline void Set(int index, MaybeObject* value);
static constexpr int SizeFor(int length) {
return kHeaderSize + length * kPointerSize;
}
DECL_INT_ACCESSORS(length)
// Get and set the length using acquire loads and release stores.
inline int synchronized_length() const;
inline void synchronized_set_length(int value);
// Gives access to raw memory which stores the array's data.
inline MaybeObject** data_start();
DECL_VERIFIER(WeakFixedArray)
class BodyDescriptor;
typedef BodyDescriptor BodyDescriptorWeak;
static const int kLengthOffset = HeapObject::kHeaderSize;
static const int kHeaderSize = kLengthOffset + kPointerSize;
static const int kMaxLength =
(FixedArray::kMaxSize - kHeaderSize) / kPointerSize;
private:
static int OffsetOfElementAt(int index) {
return kHeaderSize + index * kPointerSize;
}
friend class Heap;
static const int kFirstIndex = 1;
DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
};
// Deprecated. Use WeakFixedArray instead.
class FixedArrayOfWeakCells : public FixedArray {
public:
// If |maybe_array| is not a FixedArrayOfWeakCells, a fresh one will be

View File

@ -56,7 +56,8 @@ namespace internal {
V(Symbol) \
V(ThinString) \
V(TransitionArray) \
V(WeakCell)
V(WeakCell) \
V(WeakFixedArray)
// 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

@ -165,6 +165,10 @@
reinterpret_cast<Object*>(base::Relaxed_Load( \
reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
#define RELAXED_READ_WEAK_FIELD(p, offset) \
reinterpret_cast<MaybeObject*>(base::Relaxed_Load( \
reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
#ifdef V8_CONCURRENT_MARKING
#define WRITE_FIELD(p, offset, value) \
base::Relaxed_Store( \
@ -196,6 +200,12 @@
object, HeapObject::RawField(object, offset), value); \
heap->RecordWrite(object, HeapObject::RawField(object, offset), value);
#define WEAK_WRITE_BARRIER(heap, object, offset, value) \
heap->incremental_marking()->RecordMaybeWeakWrite( \
object, HeapObject::RawMaybeWeakField(object, offset), value); \
heap->RecordWrite(object, HeapObject::RawMaybeWeakField(object, offset), \
value);
#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
if (mode != SKIP_WRITE_BARRIER) { \
if (mode == UPDATE_WRITE_BARRIER) { \

View File

@ -1625,6 +1625,7 @@ bool V8HeapExplorer::IsEssentialObject(Object* object) {
return object->IsHeapObject() && !object->IsOddball() &&
object != heap_->empty_byte_array() &&
object != heap_->empty_fixed_array() &&
object != heap_->empty_weak_fixed_array() &&
object != heap_->empty_descriptor_array() &&
object != heap_->fixed_array_map() && object != heap_->cell_map() &&
object != heap_->global_property_cell_map() &&

View File

@ -307,6 +307,86 @@ TEST(WeakReferenceWriteBarrier) {
CHECK(fv->optimized_code_weak_or_smi()->IsWeakHeapObject());
}
TEST(EmptyWeakArray) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
HandleScope outer_scope(isolate);
Handle<WeakFixedArray> array = factory->empty_weak_fixed_array();
CHECK(array->IsWeakFixedArray());
CHECK(!array->IsFixedArray());
CHECK_EQ(array->length(), 0);
}
TEST(WeakArraysBasic) {
ManualGCScope manual_gc_scope;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope outer_scope(isolate);
const int length = 4;
Handle<WeakFixedArray> array = factory->NewWeakFixedArray(length);
CHECK(array->IsWeakFixedArray());
CHECK(!array->IsFixedArray());
CHECK_EQ(array->length(), length);
CHECK(heap->InNewSpace(*array));
for (int i = 0; i < length; ++i) {
HeapObject* heap_object;
CHECK(array->Get(i)->ToStrongHeapObject(&heap_object));
CHECK_EQ(heap_object, heap->undefined_value());
}
Handle<HeapObject> saved;
{
HandleScope inner_scope(isolate);
Handle<FixedArray> index0 = factory->NewFixedArray(1);
index0->set(0, Smi::FromInt(2016));
Handle<FixedArray> index1 = factory->NewFixedArray(1);
index1->set(0, Smi::FromInt(2017));
Handle<FixedArray> index2 = factory->NewFixedArray(1);
index2->set(0, Smi::FromInt(2018));
Handle<FixedArray> index3 = factory->NewFixedArray(1);
index3->set(0, Smi::FromInt(2019));
array->Set(0, HeapObjectReference::Weak(*index0));
array->Set(1, HeapObjectReference::Weak(*index1));
array->Set(2, HeapObjectReference::Strong(*index2));
array->Set(3, HeapObjectReference::Weak(*index3));
saved = inner_scope.CloseAndEscape(index1);
} // 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(array->Get(0)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2016);
CHECK(array->Get(1)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2017);
CHECK(array->Get(2)->ToStrongHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2018);
CHECK(array->Get(3)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2019);
CcTest::CollectAllGarbage();
CHECK(heap->InOldSpace(*array));
CHECK(array->Get(0)->IsClearedWeakHeapObject());
CHECK(array->Get(1)->ToWeakHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2017);
CHECK(array->Get(2)->ToStrongHeapObject(&heap_object));
CHECK_EQ(Smi::cast(FixedArray::cast(heap_object)->get(0))->value(), 2018);
CHECK(array->Get(3)->IsClearedWeakHeapObject());
}
} // namespace heap
} // namespace internal
} // namespace v8

View File

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