[vm] Add WeakArray; to be used to create weak canonical sets.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/50648
Change-Id: I788a8e3e5e8383c0b8d6f248d64a33dc67013260
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278860
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2023-01-17 20:33:03 +00:00 committed by Commit Queue
parent 5fbbb75c53
commit f3067e8740
16 changed files with 314 additions and 54 deletions

View file

@ -36,6 +36,7 @@ static constexpr intptr_t kClassIdTagMax = (1 << 20) - 1;
V(Namespace) \
V(KernelProgramInfo) \
V(WeakSerializationReference) \
V(WeakArray) \
V(Code) \
V(Instructions) \
V(InstructionsSection) \

View file

@ -1423,6 +1423,12 @@ class WeakSerializationReference : public AllStatic {
FINAL_CLASS();
};
class WeakArray : public AllStatic {
public:
static word InstanceSize() { return 0; }
FINAL_CLASS();
};
class SubtypeTestCache : public AllStatic {
public:
static word cache_offset();

View file

@ -30,6 +30,7 @@ namespace dart {
// - variable name
#define GC_LINKED_LIST(V) \
V(WeakProperty, weak_properties) \
V(WeakArray, weak_arrays) \
V(WeakReference, weak_references) \
V(FinalizerEntry, finalizer_entries)

View file

@ -865,6 +865,8 @@ ISOLATE_UNIT_TEST_CASE(WeakSmi) {
WeakReference::Handle(WeakReference::New(Heap::kNew));
WeakReference& old_weakref =
WeakReference::Handle(WeakReference::New(Heap::kOld));
WeakArray& new_weakarray = WeakArray::Handle(WeakArray::New(1, Heap::kNew));
WeakArray& old_weakarray = WeakArray::Handle(WeakArray::New(1, Heap::kOld));
FinalizerEntry& new_finalizer = FinalizerEntry::Handle(
FinalizerEntry::New(FinalizerBase::Handle(), Heap::kNew));
FinalizerEntry& old_finalizer = FinalizerEntry::Handle(
@ -877,6 +879,8 @@ ISOLATE_UNIT_TEST_CASE(WeakSmi) {
old_ephemeron.set_key(smi);
new_weakref.set_target(smi);
old_weakref.set_target(smi);
new_weakarray.SetAt(0, smi);
old_weakarray.SetAt(0, smi);
new_finalizer.set_value(smi);
old_finalizer.set_value(smi);
}
@ -888,6 +892,8 @@ ISOLATE_UNIT_TEST_CASE(WeakSmi) {
EXPECT(old_ephemeron.key() == Smi::New(42));
EXPECT(new_weakref.target() == Smi::New(42));
EXPECT(old_weakref.target() == Smi::New(42));
EXPECT(new_weakarray.At(0) == Smi::New(42));
EXPECT(old_weakarray.At(0) == Smi::New(42));
EXPECT(new_finalizer.value() == Smi::New(42));
EXPECT(old_finalizer.value() == Smi::New(42));
}

View file

@ -123,14 +123,13 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
intptr_t size;
if (class_id == kWeakPropertyCid) {
WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
size = ProcessWeakProperty(raw_weak);
size = ProcessWeakProperty(static_cast<WeakPropertyPtr>(raw_obj));
} else if (class_id == kWeakReferenceCid) {
WeakReferencePtr raw_weak = static_cast<WeakReferencePtr>(raw_obj);
size = ProcessWeakReference(raw_weak);
size = ProcessWeakReference(static_cast<WeakReferencePtr>(raw_obj));
} else if (class_id == kWeakArrayCid) {
size = ProcessWeakArray(static_cast<WeakArrayPtr>(raw_obj));
} else if (class_id == kFinalizerEntryCid) {
FinalizerEntryPtr raw_weak = static_cast<FinalizerEntryPtr>(raw_obj);
size = ProcessFinalizerEntry(raw_weak);
size = ProcessFinalizerEntry(static_cast<FinalizerEntryPtr>(raw_obj));
} else {
if ((class_id == kArrayCid) || (class_id == kImmutableArrayCid)) {
size = raw_obj->untag()->HeapSize();
@ -232,6 +231,11 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
return raw_weak->untag()->HeapSize();
}
intptr_t ProcessWeakArray(WeakArrayPtr raw_weak) {
delayed_.weak_arrays.Enqueue(raw_weak);
return raw_weak->untag()->HeapSize();
}
intptr_t ProcessFinalizerEntry(FinalizerEntryPtr raw_entry) {
ASSERT(IsMarked(raw_entry));
delayed_.finalizer_entries.Enqueue(raw_entry);
@ -315,6 +319,23 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
}
}
void MournWeakArrays() {
WeakArrayPtr cur_weak = delayed_.weak_arrays.Release();
while (cur_weak != WeakArray::null()) {
WeakArrayPtr next_weak =
cur_weak->untag()->next_seen_by_gc_.Decompress(cur_weak->heap_base());
cur_weak->untag()->next_seen_by_gc_ = WeakArray::null();
intptr_t length = Smi::Value(cur_weak->untag()->length());
for (intptr_t i = 0; i < length; i++) {
ForwardOrSetNullIfCollected(cur_weak->heap_base(),
&cur_weak->untag()->data()[i]);
}
cur_weak = next_weak;
}
}
// Returns whether the object referred to in `ptr_address` was GCed this GC.
static bool ForwardOrSetNullIfCollected(uword heap_base,
CompressedObjectPtr* ptr_address) {
@ -742,6 +763,7 @@ class ParallelMarkTask : public ThreadPool::Task {
// Phase 3: Weak processing and statistics.
visitor_->MournWeakProperties();
visitor_->MournWeakReferences();
visitor_->MournWeakArrays();
// Don't MournFinalized here, do it on main thread, so that we don't have
// to coordinate workers.
@ -1044,6 +1066,7 @@ void GCMarker::MarkObjects(PageSpace* page_space) {
visitor.FinalizeMarking();
visitor.MournWeakProperties();
visitor.MournWeakReferences();
visitor.MournWeakArrays();
MournFinalized(&visitor);
IterateWeakRoots(thread);
// All marking done; detach code, etc.

View file

@ -309,7 +309,8 @@ class ScavengerVisitorBase : public ObjectPointerVisitor {
}
MournWeakProperties();
MournOrUpdateWeakReferences();
MournWeakReferences();
MournWeakArrays();
MournFinalized(this);
}
page_space_->ReleaseLock(freelist_);
@ -539,7 +540,8 @@ class ScavengerVisitorBase : public ObjectPointerVisitor {
}
void MournWeakProperties();
void MournOrUpdateWeakReferences();
void MournWeakReferences();
void MournWeakArrays();
Thread* thread_;
Scavenger* scavenger_;
@ -1351,6 +1353,10 @@ intptr_t ScavengerVisitorBase<parallel>::ProcessCopied(ObjectPtr raw_obj) {
return raw_weak->untag()->HeapSize();
}
}
} else if (UNLIKELY(class_id == kWeakArrayCid)) {
WeakArrayPtr raw_weak = static_cast<WeakArrayPtr>(raw_obj);
delayed_.weak_arrays.Enqueue(raw_weak);
return raw_weak->untag()->HeapSize();
} else if (UNLIKELY(class_id == kFinalizerEntryCid)) {
FinalizerEntryPtr raw_entry = static_cast<FinalizerEntryPtr>(raw_obj);
ASSERT(IsNotForwarding(raw_entry));
@ -1484,7 +1490,7 @@ void ScavengerVisitorBase<parallel>::MournWeakProperties() {
}
template <bool parallel>
void ScavengerVisitorBase<parallel>::MournOrUpdateWeakReferences() {
void ScavengerVisitorBase<parallel>::MournWeakReferences() {
ASSERT(!scavenger_->abort_);
// The queued weak references at this point either should have their target
@ -1506,6 +1512,27 @@ void ScavengerVisitorBase<parallel>::MournOrUpdateWeakReferences() {
}
}
template <bool parallel>
void ScavengerVisitorBase<parallel>::MournWeakArrays() {
ASSERT(!scavenger_->abort_);
WeakArrayPtr cur_weak = delayed_.weak_arrays.Release();
while (cur_weak != WeakArray::null()) {
WeakArrayPtr next_weak =
cur_weak->untag()->next_seen_by_gc_.Decompress(cur_weak->heap_base());
// Reset the next pointer in the weak reference.
cur_weak->untag()->next_seen_by_gc_ = WeakArray::null();
intptr_t length = Smi::Value(cur_weak->untag()->length());
for (intptr_t i = 0; i < length; i++) {
ForwardOrSetNullIfCollected(cur_weak->heap_base(),
&(cur_weak->untag()->data()[i]));
}
// Advance to next weak reference in the queue.
cur_weak = next_weak;
}
}
// Returns whether the object referred to in `ptr_address` was GCed this GC.
template <bool parallel>
bool ScavengerVisitorBase<parallel>::ForwardOrSetNullIfCollected(

View file

@ -187,6 +187,7 @@ ClassPtr Object::unhandled_exception_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::unwind_error_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::weak_serialization_reference_class_ =
static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::weak_array_class_ = static_cast<ClassPtr>(RAW_NULL);
const double MegamorphicCache::kLoadFactor = 0.50;
@ -942,6 +943,9 @@ void Object::Init(IsolateGroup* isolate_group) {
isolate_group);
weak_serialization_reference_class_ = cls.ptr();
cls = Class::New<WeakArray, RTN::WeakArray>(isolate_group);
weak_array_class_ = cls.ptr();
ASSERT(class_class() != null_);
// Pre-allocate classes in the vm isolate so that we can for example create a
@ -1469,6 +1473,7 @@ void Object::FinalizeVMIsolate(IsolateGroup* isolate_group) {
SET_CLASS_NAME(namespace, Namespace);
SET_CLASS_NAME(kernel_program_info, KernelProgramInfo);
SET_CLASS_NAME(weak_serialization_reference, WeakSerializationReference);
SET_CLASS_NAME(weak_array, WeakArray);
SET_CLASS_NAME(code, Code);
SET_CLASS_NAME(instructions, Instructions);
SET_CLASS_NAME(instructions_section, InstructionsSection);
@ -5258,6 +5263,8 @@ const char* Class::GenerateUserVisibleName() const {
return Symbols::KernelProgramInfo().ToCString();
case kWeakSerializationReferenceCid:
return Symbols::WeakSerializationReference().ToCString();
case kWeakArrayCid:
return Symbols::WeakArray().ToCString();
case kCodeCid:
return Symbols::Code().ToCString();
case kInstructionsCid:
@ -17402,6 +17409,24 @@ ObjectPtr WeakSerializationReference::New(const Object& target,
return result.ptr();
}
const char* WeakArray::ToCString() const {
return Thread::Current()->zone()->PrintToString("WeakArray len:%" Pd,
Length());
}
WeakArrayPtr WeakArray::New(intptr_t length, Heap::Space space) {
ASSERT(Object::weak_array_class() != Class::null());
if (!IsValidLength(length)) {
// This should be caught before we reach here.
FATAL("Fatal error in WeakArray::New: invalid len %" Pd "\n", length);
}
WeakArrayPtr raw = static_cast<WeakArrayPtr>(
Object::Allocate(kWeakArrayCid, WeakArray::InstanceSize(length), space,
WeakArray::ContainsCompressedPointers()));
raw->untag()->set_length(Smi::New(length));
return raw;
}
#if defined(INCLUDE_IL_PRINTER)
Code::Comments& Code::Comments::New(intptr_t count) {
Comments* comments;

View file

@ -524,7 +524,6 @@ class Object {
static ClassPtr exception_handlers_class() {
return exception_handlers_class_;
}
static ClassPtr deopt_info_class() { return deopt_info_class_; }
static ClassPtr context_class() { return context_class_; }
static ClassPtr context_scope_class() { return context_scope_class_; }
static ClassPtr sentinel_class() { return sentinel_class_; }
@ -546,6 +545,7 @@ class Object {
static ClassPtr weak_serialization_reference_class() {
return weak_serialization_reference_class_;
}
static ClassPtr weak_array_class() { return weak_array_class_; }
// Initialize the VM isolate.
static void InitNullAndBool(IsolateGroup* isolate_group);
@ -839,51 +839,46 @@ class Object {
static BoolPtr true_;
static BoolPtr false_;
static ClassPtr class_class_; // Class of the Class vm object.
static ClassPtr dynamic_class_; // Class of the 'dynamic' type.
static ClassPtr void_class_; // Class of the 'void' type.
static ClassPtr type_parameters_class_; // Class of TypeParameters vm object.
static ClassPtr type_arguments_class_; // Class of TypeArguments vm object.
static ClassPtr patch_class_class_; // Class of the PatchClass vm object.
static ClassPtr function_class_; // Class of the Function vm object.
static ClassPtr closure_data_class_; // Class of ClosureData vm obj.
static ClassPtr ffi_trampoline_data_class_; // Class of FfiTrampolineData
// vm obj.
static ClassPtr field_class_; // Class of the Field vm object.
static ClassPtr script_class_; // Class of the Script vm object.
static ClassPtr library_class_; // Class of the Library vm object.
static ClassPtr namespace_class_; // Class of Namespace vm object.
static ClassPtr kernel_program_info_class_; // Class of KernelProgramInfo vm
// object.
static ClassPtr code_class_; // Class of the Code vm object.
static ClassPtr instructions_class_; // Class of the Instructions vm object.
static ClassPtr instructions_section_class_; // Class of InstructionsSection.
static ClassPtr instructions_table_class_; // Class of InstructionsTable.
static ClassPtr object_pool_class_; // Class of the ObjectPool vm object.
static ClassPtr pc_descriptors_class_; // Class of PcDescriptors vm object.
static ClassPtr code_source_map_class_; // Class of CodeSourceMap vm object.
static ClassPtr compressed_stackmaps_class_; // Class of CompressedStackMaps.
static ClassPtr var_descriptors_class_; // Class of LocalVarDescriptors.
static ClassPtr exception_handlers_class_; // Class of ExceptionHandlers.
static ClassPtr deopt_info_class_; // Class of DeoptInfo.
static ClassPtr context_class_; // Class of the Context vm object.
static ClassPtr context_scope_class_; // Class of ContextScope vm object.
static ClassPtr sentinel_class_; // Class of Sentinel vm object.
static ClassPtr singletargetcache_class_; // Class of SingleTargetCache.
static ClassPtr unlinkedcall_class_; // Class of UnlinkedCall.
static ClassPtr
monomorphicsmiablecall_class_; // Class of MonomorphicSmiableCall.
static ClassPtr icdata_class_; // Class of ICData.
static ClassPtr megamorphic_cache_class_; // Class of MegamorphiCache.
static ClassPtr subtypetestcache_class_; // Class of SubtypeTestCache.
static ClassPtr loadingunit_class_; // Class of LoadingUnit.
static ClassPtr api_error_class_; // Class of ApiError.
static ClassPtr language_error_class_; // Class of LanguageError.
static ClassPtr unhandled_exception_class_; // Class of UnhandledException.
static ClassPtr unwind_error_class_; // Class of UnwindError.
// Class of WeakSerializationReference.
static ClassPtr class_class_;
static ClassPtr dynamic_class_;
static ClassPtr void_class_;
static ClassPtr type_parameters_class_;
static ClassPtr type_arguments_class_;
static ClassPtr patch_class_class_;
static ClassPtr function_class_;
static ClassPtr closure_data_class_;
static ClassPtr ffi_trampoline_data_class_;
static ClassPtr field_class_;
static ClassPtr script_class_;
static ClassPtr library_class_;
static ClassPtr namespace_class_;
static ClassPtr kernel_program_info_class_;
static ClassPtr code_class_;
static ClassPtr instructions_class_;
static ClassPtr instructions_section_class_;
static ClassPtr instructions_table_class_;
static ClassPtr object_pool_class_;
static ClassPtr pc_descriptors_class_;
static ClassPtr code_source_map_class_;
static ClassPtr compressed_stackmaps_class_;
static ClassPtr var_descriptors_class_;
static ClassPtr exception_handlers_class_;
static ClassPtr context_class_;
static ClassPtr context_scope_class_;
static ClassPtr sentinel_class_;
static ClassPtr singletargetcache_class_;
static ClassPtr unlinkedcall_class_;
static ClassPtr monomorphicsmiablecall_class_;
static ClassPtr icdata_class_;
static ClassPtr megamorphic_cache_class_;
static ClassPtr subtypetestcache_class_;
static ClassPtr loadingunit_class_;
static ClassPtr api_error_class_;
static ClassPtr language_error_class_;
static ClassPtr unhandled_exception_class_;
static ClassPtr unwind_error_class_;
static ClassPtr weak_serialization_reference_class_;
static ClassPtr weak_array_class_;
#define DECLARE_SHARED_READONLY_HANDLE(Type, name) static Type* name##_;
SHARED_READONLY_HANDLES_LIST(DECLARE_SHARED_READONLY_HANDLE)
@ -6361,6 +6356,72 @@ class WeakSerializationReference : public Object {
friend class Class;
};
class WeakArray : public Object {
public:
intptr_t Length() const { return LengthOf(ptr()); }
static inline intptr_t LengthOf(const WeakArrayPtr array);
static intptr_t length_offset() {
return OFFSET_OF(UntaggedWeakArray, length_);
}
static intptr_t data_offset() {
return OFFSET_OF_RETURNED_VALUE(UntaggedWeakArray, data);
}
static intptr_t element_offset(intptr_t index) {
return OFFSET_OF_RETURNED_VALUE(UntaggedWeakArray, data) +
kBytesPerElement * index;
}
static intptr_t index_at_offset(intptr_t offset_in_bytes) {
intptr_t index = (offset_in_bytes - data_offset()) / kBytesPerElement;
ASSERT(index >= 0);
return index;
}
struct ArrayTraits {
static intptr_t elements_start_offset() { return WeakArray::data_offset(); }
static constexpr intptr_t kElementSize = kCompressedWordSize;
};
ObjectPtr At(intptr_t index) const { return untag()->element(index); }
void SetAt(intptr_t index, const Object& value) const {
untag()->set_element(index, value.ptr());
}
// Access to the array with acquire release semantics.
ObjectPtr AtAcquire(intptr_t index) const {
return untag()->element<std::memory_order_acquire>(index);
}
void SetAtRelease(intptr_t index, const Object& value) const {
untag()->set_element<std::memory_order_release>(index, value.ptr());
}
static const intptr_t kBytesPerElement = kCompressedWordSize;
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
static constexpr bool IsValidLength(intptr_t length) {
return 0 <= length && length <= kMaxElements;
}
static intptr_t InstanceSize() {
ASSERT(sizeof(UntaggedWeakArray) ==
OFFSET_OF_RETURNED_VALUE(UntaggedWeakArray, data));
return 0;
}
static constexpr intptr_t InstanceSize(intptr_t len) {
return RoundedAllocationSize(sizeof(UntaggedWeakArray) +
(len * kBytesPerElement));
}
static WeakArrayPtr New(intptr_t length, Heap::Space space = Heap::kNew);
private:
FINAL_HEAP_OBJECT_IMPLEMENTATION(WeakArray, Object);
friend class Class;
friend class Object;
};
class Code : public Object {
public:
// When dual mapping, this returns the executable view.
@ -12963,6 +13024,10 @@ void Field::set_field_id_unsafe(intptr_t field_id) const {
untag()->set_host_offset_or_field_id(Smi::New(field_id));
}
intptr_t WeakArray::LengthOf(const WeakArrayPtr array) {
return Smi::Value(array->untag()->length());
}
void Context::SetAt(intptr_t index, const Object& value) const {
untag()->set_element(index, value.ptr());
}

View file

@ -87,6 +87,7 @@
V(UnlinkedCall) \
V(UnwindError) \
V(UserTag) \
V(WeakArray) \
V(WeakSerializationReference)
namespace dart {

View file

@ -705,6 +705,35 @@ void WeakSerializationReference::PrintJSONImpl(JSONStream* stream,
jsobj.AddProperty("target", obj);
}
void WeakArray::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
jsobj.AddServiceId(*this);
jsobj.AddProperty("length", Length());
if (ref) {
return;
}
intptr_t offset;
intptr_t count;
stream->ComputeOffsetAndCount(Length(), &offset, &count);
if (offset > 0) {
jsobj.AddProperty("offset", offset);
}
if (count < Length()) {
jsobj.AddProperty("count", count);
}
intptr_t limit = offset + count;
ASSERT(limit <= Length());
{
JSONArray jsarr(&jsobj, "elements");
Object& element = Object::Handle();
for (intptr_t index = offset; index < limit; index++) {
element = At(index);
jsarr.AddValue(element);
}
}
}
void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);

View file

@ -4086,6 +4086,50 @@ ISOLATE_UNIT_TEST_CASE(
WeakReference_Preserve_ReachableThroughWeakProperty(thread, Heap::kOld);
}
ISOLATE_UNIT_TEST_CASE(WeakArray_New) {
WeakArray& array = WeakArray::Handle(WeakArray::New(2, Heap::kNew));
Object& target0 = Object::Handle();
{
HANDLESCOPE(thread);
target0 = String::New("0", Heap::kNew);
Object& target1 = Object::Handle(String::New("1", Heap::kNew));
array.SetAt(0, target0);
array.SetAt(1, target1);
}
EXPECT(array.Length() == 2);
EXPECT(array.At(0) != Object::null());
EXPECT(array.At(1) != Object::null());
GCTestHelper::CollectNewSpace();
EXPECT(array.Length() == 2);
EXPECT(array.At(0) != Object::null()); // Survives
EXPECT(array.At(1) == Object::null()); // Cleared
}
ISOLATE_UNIT_TEST_CASE(WeakArray_Old) {
WeakArray& array = WeakArray::Handle(WeakArray::New(2, Heap::kOld));
Object& target0 = Object::Handle();
{
HANDLESCOPE(thread);
target0 = String::New("0", Heap::kOld);
Object& target1 = Object::Handle(String::New("1", Heap::kOld));
array.SetAt(0, target0);
array.SetAt(1, target1);
}
EXPECT(array.Length() == 2);
EXPECT(array.At(0) != Object::null());
EXPECT(array.At(1) != Object::null());
GCTestHelper::CollectAllGarbage();
EXPECT(array.Length() == 2);
EXPECT(array.At(0) != Object::null()); // Survives
EXPECT(array.At(1) == Object::null()); // Cleared
}
static int NumEntries(const FinalizerEntry& entry, intptr_t acc = 0) {
if (entry.IsNull()) {
return acc;

View file

@ -151,6 +151,12 @@ intptr_t UntaggedObject::HeapSizeFromClass(uword tags) const {
instance_size = Array::InstanceSize(array_length);
break;
}
case kWeakArrayCid: {
const WeakArrayPtr raw_array = static_cast<const WeakArrayPtr>(this);
intptr_t array_length = Smi::Value(raw_array->untag()->length());
instance_size = WeakArray::InstanceSize(array_length);
break;
}
case kObjectPoolCid: {
const ObjectPoolPtr raw_object_pool =
static_cast<const ObjectPoolPtr>(this);
@ -529,6 +535,7 @@ COMPRESSED_VISITOR(Library)
COMPRESSED_VISITOR(Namespace)
COMPRESSED_VISITOR(KernelProgramInfo)
COMPRESSED_VISITOR(WeakSerializationReference)
VARIABLE_COMPRESSED_VISITOR(WeakArray, Smi::Value(raw_obj->untag()->length()))
COMPRESSED_VISITOR(Type)
COMPRESSED_VISITOR(FunctionType)
COMPRESSED_VISITOR(RecordType)

View file

@ -1713,6 +1713,28 @@ class UntaggedWeakSerializationReference : public UntaggedObject {
VISIT_TO(replacement)
};
class UntaggedWeakArray : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(WeakArray);
COMPRESSED_POINTER_FIELD(WeakArrayPtr, next_seen_by_gc)
COMPRESSED_SMI_FIELD(SmiPtr, length)
VISIT_FROM(length)
// Variable length data follows here.
COMPRESSED_VARIABLE_POINTER_FIELDS(ObjectPtr, element, data)
template <typename Table, bool kAllCanonicalObjectsAreIncludedIntoSet>
friend class CanonicalSetDeserializationCluster;
template <typename Type, typename PtrType>
friend class GCLinkedList;
friend class GCMarker;
template <bool>
friend class MarkingVisitorBase;
friend class Scavenger;
template <bool>
friend class ScavengerVisitorBase;
};
class UntaggedCode : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Code);

View file

@ -88,6 +88,7 @@ namespace dart {
F(KernelProgramInfo, retained_kernel_blob_) \
F(WeakSerializationReference, target_) \
F(WeakSerializationReference, replacement_) \
F(WeakArray, length_) \
F(Code, object_pool_) \
F(Code, instructions_) \
F(Code, owner_) \

View file

@ -267,6 +267,7 @@ class ObjectPointerVisitor;
V(UnwindError, "UnwindError") \
V(Value, "value") \
V(Values, "values") \
V(WeakArray, "WeakArray") \
V(WeakSerializationReference, "WeakSerializationReference") \
V(_AsyncStarStreamController, "_AsyncStarStreamController") \
V(_BufferingStreamSubscription, "_BufferingStreamSubscription") \

View file

@ -355,6 +355,7 @@ DEFINE_TAGGED_POINTER(Library, Object)
DEFINE_TAGGED_POINTER(Namespace, Object)
DEFINE_TAGGED_POINTER(KernelProgramInfo, Object)
DEFINE_TAGGED_POINTER(WeakSerializationReference, Object)
DEFINE_TAGGED_POINTER(WeakArray, Object)
DEFINE_TAGGED_POINTER(Code, Object)
DEFINE_TAGGED_POINTER(ObjectPool, Object)
DEFINE_TAGGED_POINTER(Instructions, Object)