[vm] Replace recanonicalization in primary snapshots with weak constant tables.
TEST=ci Bug: https://github.com/dart-lang/sdk/issues/41974 Change-Id: Icc4a3ebf861dca5172a0cfa2cd2eea266e814d0c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181480 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Siva Annamalai <asiva@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
c290fc0eaf
commit
25fd0200ef
@@ -28,6 +28,7 @@ typedef uint16_t ClassIdTagType;
|
||||
V(Library) \
|
||||
V(Namespace) \
|
||||
V(KernelProgramInfo) \
|
||||
V(WeakSerializationReference) \
|
||||
V(Code) \
|
||||
V(Instructions) \
|
||||
V(InstructionsSection) \
|
||||
@@ -87,8 +88,7 @@ typedef uint16_t ClassIdTagType;
|
||||
V(LinkedHashMap) \
|
||||
V(FutureOr) \
|
||||
V(UserTag) \
|
||||
V(TransferableTypedData) \
|
||||
V(WeakSerializationReference)
|
||||
V(TransferableTypedData)
|
||||
|
||||
#define CLASS_LIST_ARRAYS(V) \
|
||||
V(Array) \
|
||||
|
||||
@@ -1997,113 +1997,44 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster {
|
||||
class WeakSerializationReferenceSerializationCluster
|
||||
: public SerializationCluster {
|
||||
public:
|
||||
WeakSerializationReferenceSerializationCluster(Zone* zone, Heap* heap)
|
||||
WeakSerializationReferenceSerializationCluster()
|
||||
: SerializationCluster(
|
||||
"WeakSerializationReference",
|
||||
compiler::target::WeakSerializationReference::InstanceSize()),
|
||||
heap_(ASSERT_NOTNULL(heap)),
|
||||
objects_(zone, 0),
|
||||
canonical_wsrs_(zone, 0),
|
||||
canonical_wsr_map_(zone) {}
|
||||
compiler::target::WeakSerializationReference::InstanceSize()) {}
|
||||
~WeakSerializationReferenceSerializationCluster() {}
|
||||
|
||||
void Trace(Serializer* s, ObjectPtr object) {
|
||||
ASSERT(s->kind() == Snapshot::kFullAOT);
|
||||
// Make sure we don't trace again after choosing canonical WSRs.
|
||||
ASSERT(!have_canonicalized_wsrs_);
|
||||
|
||||
auto const ref = WeakSerializationReference::RawCast(object);
|
||||
objects_.Add(ref);
|
||||
// We do _not_ push the target, since this is not a strong reference.
|
||||
WeakSerializationReferencePtr weak =
|
||||
WeakSerializationReference::RawCast(object);
|
||||
objects_.Add(weak);
|
||||
}
|
||||
|
||||
intptr_t FinalizeWeak(Serializer* s) { return objects_.length(); }
|
||||
|
||||
void WriteAlloc(Serializer* s) {
|
||||
ASSERT(s->kind() == Snapshot::kFullAOT);
|
||||
ASSERT(have_canonicalized_wsrs_);
|
||||
|
||||
s->WriteCid(kWeakSerializationReferenceCid);
|
||||
s->WriteUnsigned(WrittenCount());
|
||||
|
||||
// Set up references for those objects that will be written.
|
||||
for (auto const& ref : canonical_wsrs_) {
|
||||
s->AssignRef(ref);
|
||||
}
|
||||
|
||||
// In precompiled mode, set the object ID of each non-canonical WSR to
|
||||
// its canonical counterpart's object ID. This ensures that any reference to
|
||||
// it is serialized as a reference to the canonicalized one.
|
||||
for (auto const& ref : objects_) {
|
||||
ASSERT(IsReachableReference(heap_->GetObjectId(ref)));
|
||||
if (ShouldDrop(ref)) {
|
||||
// For dropped references, reset their ID to be the unreachable
|
||||
// reference value, so RefId retrieves the target ID instead.
|
||||
heap_->SetObjectId(ref, kUnreachableReference);
|
||||
continue;
|
||||
}
|
||||
// Skip if we've already allocated a reference (this is a canonical WSR).
|
||||
if (IsAllocatedReference(heap_->GetObjectId(ref))) continue;
|
||||
auto const target_cid = WeakSerializationReference::TargetClassIdOf(ref);
|
||||
ASSERT(canonical_wsr_map_.HasKey(target_cid));
|
||||
auto const canonical_index = canonical_wsr_map_.Lookup(target_cid) - 1;
|
||||
auto const canonical_wsr = objects_[canonical_index];
|
||||
// Set the object ID of this non-canonical WSR to the same as its
|
||||
// canonical WSR entry, so we'll reference the canonical WSR when
|
||||
// serializing references to this object.
|
||||
auto const canonical_heap_id = heap_->GetObjectId(canonical_wsr);
|
||||
ASSERT(IsAllocatedReference(canonical_heap_id));
|
||||
heap_->SetObjectId(ref, canonical_heap_id);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFill(Serializer* s) {
|
||||
ASSERT(s->kind() == Snapshot::kFullAOT);
|
||||
for (auto const& ref : canonical_wsrs_) {
|
||||
AutoTraceObject(ref);
|
||||
|
||||
// In precompiled mode, we drop the reference to the target and only
|
||||
// keep the class ID.
|
||||
s->WriteCid(WeakSerializationReference::TargetClassIdOf(ref));
|
||||
}
|
||||
}
|
||||
|
||||
// Picks a WSR for each target class ID to be canonical. Should only be run
|
||||
// after all objects have been traced.
|
||||
void CanonicalizeReferences() {
|
||||
ASSERT(!have_canonicalized_wsrs_);
|
||||
void ForwardWeakRefs(Serializer* s) {
|
||||
Heap* heap = s->heap();
|
||||
for (intptr_t i = 0; i < objects_.length(); i++) {
|
||||
auto const ref = objects_[i];
|
||||
if (ShouldDrop(ref)) continue;
|
||||
auto const target_cid = WeakSerializationReference::TargetClassIdOf(ref);
|
||||
if (canonical_wsr_map_.HasKey(target_cid)) continue;
|
||||
canonical_wsr_map_.Insert(target_cid, i + 1);
|
||||
canonical_wsrs_.Add(ref);
|
||||
WeakSerializationReferencePtr weak = objects_[i];
|
||||
|
||||
intptr_t id = heap->GetObjectId(weak->untag()->target());
|
||||
if (id == kUnreachableReference) {
|
||||
id = heap->GetObjectId(weak->untag()->replacement());
|
||||
ASSERT(id != kUnreachableReference);
|
||||
}
|
||||
ASSERT(IsAllocatedReference(id));
|
||||
heap->SetObjectId(weak, id);
|
||||
}
|
||||
have_canonicalized_wsrs_ = true;
|
||||
}
|
||||
|
||||
intptr_t WrittenCount() const {
|
||||
ASSERT(have_canonicalized_wsrs_);
|
||||
return canonical_wsrs_.length();
|
||||
}
|
||||
|
||||
intptr_t DroppedCount() const { return TotalCount() - WrittenCount(); }
|
||||
|
||||
intptr_t TotalCount() const { return objects_.length(); }
|
||||
void WriteFill(Serializer* s) {}
|
||||
|
||||
private:
|
||||
// Returns whether a WSR should be dropped due to its target being reachable
|
||||
// via strong references. WSRs only wrap heap objects, so we can just retrieve
|
||||
// the object ID from the heap directly.
|
||||
bool ShouldDrop(WeakSerializationReferencePtr ref) const {
|
||||
auto const target = WeakSerializationReference::TargetOf(ref);
|
||||
return IsReachableReference(heap_->GetObjectId(target));
|
||||
}
|
||||
|
||||
Heap* const heap_;
|
||||
GrowableArray<WeakSerializationReferencePtr> objects_;
|
||||
GrowableArray<WeakSerializationReferencePtr> canonical_wsrs_;
|
||||
IntMap<intptr_t> canonical_wsr_map_;
|
||||
bool have_canonicalized_wsrs_ = false;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -2115,29 +2046,8 @@ class WeakSerializationReferenceDeserializationCluster
|
||||
: DeserializationCluster("WeakSerializationReference") {}
|
||||
~WeakSerializationReferenceDeserializationCluster() {}
|
||||
|
||||
void ReadAlloc(Deserializer* d, bool is_canonical) {
|
||||
start_index_ = d->next_index();
|
||||
PageSpace* old_space = d->heap()->old_space();
|
||||
const intptr_t count = d->ReadUnsigned();
|
||||
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
auto ref = AllocateUninitialized(
|
||||
old_space, WeakSerializationReference::InstanceSize());
|
||||
d->AssignRef(ref);
|
||||
}
|
||||
|
||||
stop_index_ = d->next_index();
|
||||
}
|
||||
|
||||
void ReadFill(Deserializer* d, bool is_canonical) {
|
||||
for (intptr_t id = start_index_; id < stop_index_; id++) {
|
||||
auto const ref = static_cast<WeakSerializationReferencePtr>(d->Ref(id));
|
||||
Deserializer::InitializeHeader(
|
||||
ref, kWeakSerializationReferenceCid,
|
||||
WeakSerializationReference::InstanceSize());
|
||||
ref->untag()->cid_ = d->ReadCid();
|
||||
}
|
||||
}
|
||||
void ReadAlloc(Deserializer* d, bool stamp_canonical) {}
|
||||
void ReadFill(Deserializer* d, bool stamp_canonical) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -5008,7 +4918,7 @@ class VMDeserializationRoots : public DeserializationRoots {
|
||||
public:
|
||||
VMDeserializationRoots() : symbol_table_(Array::Handle()) {}
|
||||
|
||||
void AddBaseObjects(Deserializer* d) {
|
||||
bool AddBaseObjects(Deserializer* d) {
|
||||
// These objects are always allocated by Object::InitOnce, so they are not
|
||||
// written into the snapshot.
|
||||
|
||||
@@ -5057,6 +4967,8 @@ class VMDeserializationRoots : public DeserializationRoots {
|
||||
d->AddBaseObject(StubCode::EntryAt(i).ptr());
|
||||
}
|
||||
}
|
||||
|
||||
return true; // primary
|
||||
}
|
||||
|
||||
void ReadRoots(Deserializer* d) {
|
||||
@@ -5101,43 +5013,26 @@ class ProgramSerializationRoots : public SerializationRoots {
|
||||
ObjectStore* object_store)
|
||||
: base_objects_(base_objects),
|
||||
object_store_(object_store),
|
||||
saved_symbol_table_(Array::Handle()),
|
||||
saved_canonical_types_(Array::Handle()),
|
||||
saved_canonical_function_types_(Array::Handle()),
|
||||
saved_canonical_type_parameters_(Array::Handle()),
|
||||
saved_canonical_type_arguments_(Array::Handle()),
|
||||
dispatch_table_entries_(Array::Handle()) {
|
||||
saved_symbol_table_ = object_store->symbol_table();
|
||||
object_store->set_symbol_table(
|
||||
Array::Handle(HashTables::New<CanonicalStringSet>(4)));
|
||||
|
||||
saved_canonical_types_ = object_store->canonical_types();
|
||||
object_store->set_canonical_types(
|
||||
Array::Handle(HashTables::New<CanonicalTypeSet>(4)));
|
||||
|
||||
saved_canonical_function_types_ = object_store->canonical_function_types();
|
||||
object_store->set_canonical_function_types(
|
||||
Array::Handle(HashTables::New<CanonicalFunctionTypeSet>(4)));
|
||||
|
||||
saved_canonical_type_parameters_ =
|
||||
object_store->canonical_type_parameters();
|
||||
object_store->set_canonical_type_parameters(
|
||||
Array::Handle(HashTables::New<CanonicalTypeParameterSet>(4)));
|
||||
|
||||
saved_canonical_type_arguments_ = object_store->canonical_type_arguments();
|
||||
object_store->set_canonical_type_arguments(
|
||||
Array::Handle(HashTables::New<CanonicalTypeArgumentsSet>(4)));
|
||||
}
|
||||
~ProgramSerializationRoots() {
|
||||
object_store_->set_symbol_table(saved_symbol_table_);
|
||||
object_store_->set_canonical_types(saved_canonical_types_);
|
||||
object_store_->set_canonical_function_types(
|
||||
saved_canonical_function_types_);
|
||||
object_store_->set_canonical_type_parameters(
|
||||
saved_canonical_type_parameters_);
|
||||
object_store_->set_canonical_type_arguments(
|
||||
saved_canonical_type_arguments_);
|
||||
#if defined(DART_PRECOMPILER)
|
||||
if (FLAG_precompiled_mode) {
|
||||
// Elements of constant tables are treated as weak so literals used only
|
||||
// in deferred libraries do not end up in the main snapshot.
|
||||
Array& table = Array::Handle();
|
||||
table = object_store->symbol_table();
|
||||
HashTables::Weaken(table);
|
||||
table = object_store->canonical_types();
|
||||
HashTables::Weaken(table);
|
||||
table = object_store->canonical_function_types();
|
||||
HashTables::Weaken(table);
|
||||
table = object_store->canonical_type_parameters();
|
||||
HashTables::Weaken(table);
|
||||
table = object_store->canonical_type_arguments();
|
||||
HashTables::Weaken(table);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
~ProgramSerializationRoots() {}
|
||||
|
||||
void AddBaseObjects(Serializer* s) {
|
||||
if (base_objects_ == nullptr) {
|
||||
@@ -5192,11 +5087,6 @@ class ProgramSerializationRoots : public SerializationRoots {
|
||||
private:
|
||||
ZoneGrowableArray<Object*>* base_objects_;
|
||||
ObjectStore* object_store_;
|
||||
Array& saved_symbol_table_;
|
||||
Array& saved_canonical_types_;
|
||||
Array& saved_canonical_function_types_;
|
||||
Array& saved_canonical_type_parameters_;
|
||||
Array& saved_canonical_type_arguments_;
|
||||
Array& dispatch_table_entries_;
|
||||
};
|
||||
#endif // !DART_PRECOMPILED_RUNTIME
|
||||
@@ -5206,12 +5096,13 @@ class ProgramDeserializationRoots : public DeserializationRoots {
|
||||
explicit ProgramDeserializationRoots(ObjectStore* object_store)
|
||||
: object_store_(object_store) {}
|
||||
|
||||
void AddBaseObjects(Deserializer* d) {
|
||||
bool AddBaseObjects(Deserializer* d) {
|
||||
// N.B.: Skipping index 0 because ref 0 is illegal.
|
||||
const Array& base_objects = Object::vm_isolate_snapshot_object_table();
|
||||
for (intptr_t i = kFirstReference; i < base_objects.Length(); i++) {
|
||||
d->AddBaseObject(base_objects.At(i));
|
||||
}
|
||||
return true; // primary
|
||||
}
|
||||
|
||||
void ReadRoots(Deserializer* d) {
|
||||
@@ -5312,12 +5203,13 @@ class UnitDeserializationRoots : public DeserializationRoots {
|
||||
public:
|
||||
explicit UnitDeserializationRoots(const LoadingUnit& unit) : unit_(unit) {}
|
||||
|
||||
void AddBaseObjects(Deserializer* d) {
|
||||
bool AddBaseObjects(Deserializer* d) {
|
||||
const Array& base_objects =
|
||||
Array::Handle(LoadingUnit::Handle(unit_.parent()).base_objects());
|
||||
for (intptr_t i = kFirstReference; i < base_objects.Length(); i++) {
|
||||
d->AddBaseObject(base_objects.At(i));
|
||||
}
|
||||
return false; // primary
|
||||
}
|
||||
|
||||
void ReadRoots(Deserializer* d) {
|
||||
@@ -5326,7 +5218,8 @@ class UnitDeserializationRoots : public DeserializationRoots {
|
||||
for (intptr_t id = deferred_start_index_; id < deferred_stop_index_; id++) {
|
||||
CodePtr code = static_cast<CodePtr>(d->Ref(id));
|
||||
d->ReadInstructions(code, false);
|
||||
if (code->untag()->owner_->IsFunction()) {
|
||||
if (code->untag()->owner_->IsHeapObject() &&
|
||||
code->untag()->owner_->IsFunction()) {
|
||||
FunctionPtr func = static_cast<FunctionPtr>(code->untag()->owner_);
|
||||
uword entry_point = code->untag()->entry_point_;
|
||||
ASSERT(entry_point != 0);
|
||||
@@ -5731,8 +5624,7 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
|
||||
case kWeakSerializationReferenceCid:
|
||||
#if defined(DART_PRECOMPILER)
|
||||
ASSERT(kind_ == Snapshot::kFullAOT);
|
||||
return new (Z)
|
||||
WeakSerializationReferenceSerializationCluster(zone_, heap_);
|
||||
return new (Z) WeakSerializationReferenceSerializationCluster();
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
@@ -5988,16 +5880,10 @@ ZoneGrowableArray<Object*>* Serializer::Serialize(SerializationRoots* roots) {
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
// Before we finalize the count of written objects, pick canonical versions
|
||||
// of WSR objects that will be serialized and then remove any non-serialized
|
||||
// or non-canonical WSR objects from that count.
|
||||
if (auto const cluster =
|
||||
reinterpret_cast<WeakSerializationReferenceSerializationCluster*>(
|
||||
clusters_by_cid_[kWeakSerializationReferenceCid])) {
|
||||
cluster->CanonicalizeReferences();
|
||||
auto const dropped_count = cluster->DroppedCount();
|
||||
ASSERT(dropped_count == 0 || kind() == Snapshot::kFullAOT);
|
||||
num_written_objects_ -= dropped_count;
|
||||
num_written_objects_ -= cluster->FinalizeWeak(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6038,6 +5924,12 @@ ZoneGrowableArray<Object*>* Serializer::Serialize(SerializationRoots* roots) {
|
||||
ASSERT(objects_->length() == num_objects);
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
if (auto cluster =
|
||||
reinterpret_cast<WeakSerializationReferenceSerializationCluster*>(
|
||||
clusters_by_cid_[kWeakSerializationReferenceCid])) {
|
||||
cluster->ForwardWeakRefs(this);
|
||||
}
|
||||
|
||||
// When writing snapshot profile, we want to retain some of the program
|
||||
// structure information (e.g. information about libraries, classes and
|
||||
// functions - even if it was dropped when writing snapshot itself).
|
||||
@@ -6760,6 +6652,7 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||
ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len);
|
||||
}
|
||||
|
||||
bool primary;
|
||||
{
|
||||
// The deserializer initializes objects without using the write barrier,
|
||||
// partly for speed since we know all the deserialized objects will be
|
||||
@@ -6777,7 +6670,7 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||
NoSafepointScope no_safepoint;
|
||||
refs_ = refs.ptr();
|
||||
|
||||
roots->AddBaseObjects(this);
|
||||
primary = roots->AddBaseObjects(this);
|
||||
|
||||
if (num_base_objects_ != (next_ref_index_ - kFirstReference)) {
|
||||
FATAL2("Snapshot expects %" Pd
|
||||
@@ -6813,8 +6706,8 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||
{
|
||||
TIMELINE_DURATION(thread(), Isolate, "ReadFill");
|
||||
for (intptr_t i = 0; i < num_canonical_clusters_; i++) {
|
||||
TIMELINE_DURATION(thread(), Isolate, canonical_clusters_[i]->name());
|
||||
canonical_clusters_[i]->ReadFill(this, /*is_canonical*/ true);
|
||||
bool stamp_canonical = primary;
|
||||
canonical_clusters_[i]->ReadFill(this, stamp_canonical);
|
||||
#if defined(DEBUG)
|
||||
int32_t section_marker = Read<int32_t>();
|
||||
ASSERT(section_marker == kSectionMarker);
|
||||
@@ -6858,7 +6751,8 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||
TIMELINE_DURATION(thread(), Isolate, "PostLoad");
|
||||
for (intptr_t i = 0; i < num_canonical_clusters_; i++) {
|
||||
TIMELINE_DURATION(thread(), Isolate, canonical_clusters_[i]->name());
|
||||
canonical_clusters_[i]->PostLoad(this, refs, /*is_canonical*/ true);
|
||||
bool canonicalize = !primary;
|
||||
canonical_clusters_[i]->PostLoad(this, refs, canonicalize);
|
||||
}
|
||||
for (intptr_t i = 0; i < num_clusters_; i++) {
|
||||
TIMELINE_DURATION(thread(), Isolate, clusters_[i]->name());
|
||||
|
||||
@@ -163,7 +163,11 @@ class SerializationRoots {
|
||||
class DeserializationRoots {
|
||||
public:
|
||||
virtual ~DeserializationRoots() {}
|
||||
virtual void AddBaseObjects(Deserializer* deserializer) = 0;
|
||||
// Returns true if these roots are the first snapshot loaded into a heap, and
|
||||
// so can assume any canonical objects don't already exist. Returns false if
|
||||
// some other snapshot may be loaded before these roots, and so written
|
||||
// canonical objects need to run canoncalization during load.
|
||||
virtual bool AddBaseObjects(Deserializer* deserializer) = 0;
|
||||
virtual void ReadRoots(Deserializer* deserializer) = 0;
|
||||
virtual void PostLoad(Deserializer* deserializer, const Array& refs) = 0;
|
||||
};
|
||||
@@ -412,17 +416,8 @@ class Serializer : public ThreadStackResource {
|
||||
return -id;
|
||||
}
|
||||
ASSERT(!IsArtificialReference(id));
|
||||
if (IsAllocatedReference(id)) return id;
|
||||
if (object->IsWeakSerializationReference()) {
|
||||
// If a reachable WSR has an object ID of 0, then its target was marked
|
||||
// for serialization due to reachable strong references and the WSR will
|
||||
// be dropped instead. Thus, we change the reference to the WSR to a
|
||||
// direct reference to the serialized target.
|
||||
auto const ref = WeakSerializationReference::RawCast(object);
|
||||
auto const target = WeakSerializationReference::TargetOf(ref);
|
||||
auto const target_id = heap_->GetObjectId(target);
|
||||
ASSERT(IsAllocatedReference(target_id));
|
||||
return target_id;
|
||||
if (IsAllocatedReference(id)) {
|
||||
return id;
|
||||
}
|
||||
if (object->IsCode() && !Snapshot::IncludesCode(kind_)) {
|
||||
return RefId(Object::null());
|
||||
|
||||
@@ -1749,7 +1749,8 @@ void Precompiler::DropFunctions() {
|
||||
// Wrap the owner of the code object in case the code object will be
|
||||
// serialized but the function object will not.
|
||||
owner = code.owner();
|
||||
owner = WeakSerializationReference::Wrap(Z, owner);
|
||||
owner = WeakSerializationReference::New(
|
||||
owner, Smi::Handle(Smi::New(owner.GetClassId())));
|
||||
code.set_owner(owner);
|
||||
}
|
||||
dropped_function_count_++;
|
||||
@@ -2287,6 +2288,14 @@ void Precompiler::DropClasses() {
|
||||
ClassTable* class_table = IG->class_table();
|
||||
intptr_t num_cids = class_table->NumCids();
|
||||
|
||||
for (intptr_t cid = 0; cid < num_cids; cid++) {
|
||||
if (!class_table->IsValidIndex(cid)) continue;
|
||||
if (!class_table->HasValidClassAt(cid)) continue;
|
||||
cls = class_table->At(cid);
|
||||
constants = cls.constants();
|
||||
HashTables::Weaken(constants);
|
||||
}
|
||||
|
||||
for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
|
||||
if (!class_table->IsValidIndex(cid)) continue;
|
||||
if (!class_table->HasValidClassAt(cid)) continue;
|
||||
|
||||
@@ -544,7 +544,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 8;
|
||||
WeakSerializationReference_InstanceSize = 12;
|
||||
#endif // defined(TARGET_ARCH_ARM) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -1082,7 +1082,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_IA32) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -1609,7 +1609,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 8;
|
||||
WeakSerializationReference_InstanceSize = 12;
|
||||
#endif // defined(TARGET_ARCH_IA32) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -2148,7 +2148,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -2686,7 +2686,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -3225,7 +3225,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#else // !defined(PRODUCT)
|
||||
@@ -3751,7 +3751,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 8;
|
||||
WeakSerializationReference_InstanceSize = 12;
|
||||
#endif // defined(TARGET_ARCH_ARM) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -4283,7 +4283,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_IA32) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -4804,7 +4804,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 8;
|
||||
WeakSerializationReference_InstanceSize = 12;
|
||||
#endif // defined(TARGET_ARCH_IA32) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -5337,7 +5337,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -5869,7 +5869,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -6402,7 +6402,7 @@ static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
WeakSerializationReference_InstanceSize = 16;
|
||||
WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#endif // !defined(PRODUCT)
|
||||
@@ -6997,7 +6997,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 8;
|
||||
AOT_WeakSerializationReference_InstanceSize = 12;
|
||||
#endif // defined(TARGET_ARCH_ARM) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -7592,7 +7592,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_IA32) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -8191,7 +8191,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -8786,7 +8786,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -9382,7 +9382,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#else // !defined(PRODUCT)
|
||||
@@ -9968,7 +9968,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 8;
|
||||
AOT_WeakSerializationReference_InstanceSize = 12;
|
||||
#endif // defined(TARGET_ARCH_ARM) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -10556,7 +10556,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_IA32) && !defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -11148,7 +11148,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && !defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -11736,7 +11736,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
@@ -12325,7 +12325,7 @@ static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_WeakSerializationReference_InstanceSize = 16;
|
||||
AOT_WeakSerializationReference_InstanceSize = 24;
|
||||
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
|
||||
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
+29
-6
@@ -152,7 +152,9 @@ class HashTable : public ValueObject {
|
||||
template <typename Key>
|
||||
intptr_t FindKey(const Key& key) const {
|
||||
const intptr_t num_entries = NumEntries();
|
||||
ASSERT(NumOccupied() < num_entries);
|
||||
// Deleted may undercount due to weak references used during AOT
|
||||
// snapshotting.
|
||||
NOT_IN_PRECOMPILED(ASSERT(NumOccupied() < num_entries));
|
||||
// TODO(koda): Add salt.
|
||||
NOT_IN_PRODUCT(intptr_t collisions = 0;)
|
||||
uword hash = KeyTraits::Hash(key);
|
||||
@@ -188,7 +190,9 @@ class HashTable : public ValueObject {
|
||||
bool FindKeyOrDeletedOrUnused(const Key& key, intptr_t* entry) const {
|
||||
const intptr_t num_entries = NumEntries();
|
||||
ASSERT(entry != NULL);
|
||||
ASSERT(NumOccupied() < num_entries);
|
||||
// Deleted may undercount due to weak references used during AOT
|
||||
// snapshotting.
|
||||
NOT_IN_PRECOMPILED(ASSERT(NumOccupied() < num_entries));
|
||||
NOT_IN_PRODUCT(intptr_t collisions = 0;)
|
||||
uword hash = KeyTraits::Hash(key);
|
||||
ASSERT(Utils::IsPowerOfTwo(num_entries));
|
||||
@@ -236,7 +240,9 @@ class HashTable : public ValueObject {
|
||||
}
|
||||
InternalSetKey(entry, key);
|
||||
ASSERT(IsOccupied(entry));
|
||||
ASSERT(NumOccupied() < NumEntries());
|
||||
// Deleted may undercount due to weak references used during AOT
|
||||
// snapshotting.
|
||||
NOT_IN_PRECOMPILED(ASSERT(NumOccupied() < NumEntries()));
|
||||
}
|
||||
|
||||
const Object& UnusedMarker() const { return Object::transition_sentinel(); }
|
||||
@@ -258,7 +264,8 @@ class HashTable : public ValueObject {
|
||||
}
|
||||
ObjectPtr GetPayload(intptr_t entry, intptr_t component) const {
|
||||
ASSERT(IsOccupied(entry));
|
||||
return data_->At(PayloadIndex(entry, component));
|
||||
return WeakSerializationReference::Unwrap(
|
||||
data_->At(PayloadIndex(entry, component)));
|
||||
}
|
||||
void UpdatePayload(intptr_t entry,
|
||||
intptr_t component,
|
||||
@@ -371,7 +378,7 @@ class HashTable : public ValueObject {
|
||||
}
|
||||
|
||||
ObjectPtr InternalGetKey(intptr_t entry) const {
|
||||
return data_->At(KeyIndex(entry));
|
||||
return WeakSerializationReference::Unwrap(data_->At(KeyIndex(entry)));
|
||||
}
|
||||
|
||||
void InternalSetKey(intptr_t entry, const Object& key) const {
|
||||
@@ -531,6 +538,22 @@ class HashTables : public AllStatic {
|
||||
}
|
||||
return result.ptr();
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
// Replace elements of this set with WeakSerializationReferences.
|
||||
static void Weaken(const Array& table) {
|
||||
if (!table.IsNull()) {
|
||||
Object& element = Object::Handle();
|
||||
for (intptr_t i = 0; i < table.Length(); i++) {
|
||||
element = table.At(i);
|
||||
if (!element.IsSmi()) {
|
||||
element = WeakSerializationReference::New(element, table);
|
||||
table.SetAt(i, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename BaseIterTable>
|
||||
@@ -724,7 +747,7 @@ class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
|
||||
void Dump() const {
|
||||
Object& entry = Object::Handle();
|
||||
for (intptr_t i = 0; i < this->data_->Length(); i++) {
|
||||
entry = this->data_->At(i);
|
||||
entry = WeakSerializationReference::Unwrap(this->data_->At(i));
|
||||
if (entry.ptr() == BaseSet::UnusedMarker().ptr() ||
|
||||
entry.ptr() == BaseSet::DeletedMarker().ptr() || entry.IsSmi()) {
|
||||
// empty, deleted, num_used/num_deleted
|
||||
|
||||
+15
-18
@@ -1325,6 +1325,7 @@ void Object::FinalizeVMIsolate(IsolateGroup* isolate_group) {
|
||||
SET_CLASS_NAME(library, LibraryClass);
|
||||
SET_CLASS_NAME(namespace, Namespace);
|
||||
SET_CLASS_NAME(kernel_program_info, KernelProgramInfo);
|
||||
SET_CLASS_NAME(weak_serialization_reference, WeakSerializationReference);
|
||||
SET_CLASS_NAME(code, Code);
|
||||
SET_CLASS_NAME(instructions, Instructions);
|
||||
SET_CLASS_NAME(instructions_section, InstructionsSection);
|
||||
@@ -4767,6 +4768,8 @@ const char* Class::GenerateUserVisibleName() const {
|
||||
return Symbols::Namespace().ToCString();
|
||||
case kKernelProgramInfoCid:
|
||||
return Symbols::KernelProgramInfo().ToCString();
|
||||
case kWeakSerializationReferenceCid:
|
||||
return Symbols::WeakSerializationReference().ToCString();
|
||||
case kCodeCid:
|
||||
return Symbols::Code().ToCString();
|
||||
case kInstructionsCid:
|
||||
@@ -16027,26 +16030,14 @@ ICDataPtr ICData::Clone(const ICData& from) {
|
||||
#endif
|
||||
|
||||
const char* WeakSerializationReference::ToCString() const {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
return Symbols::OptimizedOut().ToCString();
|
||||
#else
|
||||
return Object::Handle(target()).ToCString();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
bool WeakSerializationReference::CanWrap(const Object& object) {
|
||||
// Currently we do not wrap the null object (which cannot be dropped from
|
||||
// snapshots), non-heap objects, and WSRs (as there is no point in deeply
|
||||
// nesting them). We also only wrap objects in the precompiler.
|
||||
return FLAG_precompiled_mode && !object.IsNull() &&
|
||||
object.ptr()->IsHeapObject() && !object.IsWeakSerializationReference();
|
||||
}
|
||||
|
||||
ObjectPtr WeakSerializationReference::Wrap(Zone* zone, const Object& target) {
|
||||
if (!CanWrap(target)) return target.ptr();
|
||||
WeakSerializationReferencePtr WeakSerializationReference::New(
|
||||
const Object& target,
|
||||
const Object& replacement) {
|
||||
ASSERT(Object::weak_serialization_reference_class() != Class::null());
|
||||
WeakSerializationReference& result = WeakSerializationReference::Handle(zone);
|
||||
WeakSerializationReference& result = WeakSerializationReference::Handle();
|
||||
{
|
||||
ObjectPtr raw = Object::Allocate(WeakSerializationReference::kClassId,
|
||||
WeakSerializationReference::InstanceSize(),
|
||||
@@ -16055,10 +16046,10 @@ ObjectPtr WeakSerializationReference::Wrap(Zone* zone, const Object& target) {
|
||||
|
||||
result ^= raw;
|
||||
result.untag()->set_target(target.ptr());
|
||||
result.untag()->set_replacement(replacement.ptr());
|
||||
}
|
||||
return result.ptr();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(INCLUDE_IL_PRINTER)
|
||||
Code::Comments& Code::Comments::New(intptr_t count) {
|
||||
@@ -24772,6 +24763,7 @@ const char* StackTrace::ToCString() const {
|
||||
auto const T = Thread::Current();
|
||||
auto const zone = T->zone();
|
||||
auto& stack_trace = StackTrace::Handle(zone, this->ptr());
|
||||
auto& owner = Object::Handle(zone);
|
||||
auto& function = Function::Handle(zone);
|
||||
auto& code_object = Object::Handle(zone);
|
||||
auto& code = Code::Handle(zone);
|
||||
@@ -24861,7 +24853,12 @@ const char* StackTrace::ToCString() const {
|
||||
ASSERT(code_object.IsCode());
|
||||
code ^= code_object.ptr();
|
||||
ASSERT(code.IsFunctionCode());
|
||||
function = code.function();
|
||||
owner = code.owner();
|
||||
if (owner.IsFunction()) {
|
||||
function ^= owner.ptr();
|
||||
} else {
|
||||
function = Function::null();
|
||||
}
|
||||
const uword pc = code.PayloadStart() + pc_offset;
|
||||
|
||||
// If the function is not to be shown, skip.
|
||||
|
||||
+22
-73
@@ -5853,87 +5853,32 @@ class ExceptionHandlers : public Object {
|
||||
//
|
||||
// Current uses of WSRs:
|
||||
// * Code::owner_
|
||||
// * Canonical table elements
|
||||
class WeakSerializationReference : public Object {
|
||||
public:
|
||||
ObjectPtr target() const { return TargetOf(ptr()); }
|
||||
static ObjectPtr TargetOf(const WeakSerializationReferencePtr raw) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
// WSRs in the precompiled runtime only contain some remaining info about
|
||||
// their old target, not a reference to the target itself..
|
||||
return Object::null();
|
||||
#else
|
||||
// Outside the precompiled runtime, they should always have a target.
|
||||
ASSERT(raw->untag()->target() != Object::null());
|
||||
return raw->untag()->target();
|
||||
#endif
|
||||
static ObjectPtr TargetOf(const WeakSerializationReferencePtr obj) {
|
||||
return obj->untag()->target();
|
||||
}
|
||||
|
||||
classid_t TargetClassId() const { return TargetClassIdOf(ptr()); }
|
||||
static classid_t TargetClassIdOf(const WeakSerializationReferencePtr raw) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
// No new instances of WSRs are created in the precompiled runtime, so
|
||||
// this instance came from deserialization and thus must be the empty WSR.
|
||||
return raw->untag()->cid_;
|
||||
#else
|
||||
return TargetOf(raw)->GetClassId();
|
||||
#endif
|
||||
}
|
||||
|
||||
static ObjectPtr Unwrap(const Object& obj) { return Unwrap(obj.ptr()); }
|
||||
// Gets the underlying object from a WSR, or the original object if it is
|
||||
// not one. Notably, Unwrap(Wrap(r)) == r for all raw objects r, whether
|
||||
// CanWrap(r) or not. However, this will not hold if a serialization and
|
||||
// deserialization step is put between the two calls.
|
||||
static ObjectPtr Unwrap(ObjectPtr obj) {
|
||||
if (!obj->IsWeakSerializationReference()) return obj;
|
||||
return TargetOf(static_cast<WeakSerializationReferencePtr>(obj));
|
||||
}
|
||||
|
||||
// An Unwrap that only unwraps if there's a valid target, otherwise the
|
||||
// WSR is returned. Useful for cases where we want to call Object methods
|
||||
// like ToCString() on whatever non-null object we can get.
|
||||
static ObjectPtr UnwrapIfTarget(const Object& obj) {
|
||||
return UnwrapIfTarget(obj.ptr());
|
||||
}
|
||||
static ObjectPtr UnwrapIfTarget(ObjectPtr raw) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
// In the precompiled runtime, WSRs never have a target so we always return
|
||||
// the argument.
|
||||
return raw;
|
||||
#else
|
||||
if (!raw->IsWeakSerializationReference()) return raw;
|
||||
// Otherwise, they always do.
|
||||
return TargetOf(WeakSerializationReference::RawCast(raw));
|
||||
#if defined(DART_PRECOMPILER)
|
||||
if (obj->IsHeapObject() && obj->IsWeakSerializationReference()) {
|
||||
return TargetOf(static_cast<WeakSerializationReferencePtr>(obj));
|
||||
}
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
static classid_t UnwrappedClassIdOf(const Object& obj) {
|
||||
return UnwrappedClassIdOf(obj.ptr());
|
||||
}
|
||||
// Gets the class ID of the underlying object from a WSR, or the class ID of
|
||||
// the object if it is not one.
|
||||
//
|
||||
// UnwrappedClassOf(Wrap(r)) == UnwrappedClassOf(r) for all raw objects r,
|
||||
// whether CanWrap(r) or not. Unlike Unwrap, this is still true even if
|
||||
// there is a serialization and deserialization step between the two calls,
|
||||
// since that information is saved in the serialized WSR.
|
||||
static classid_t UnwrappedClassIdOf(ObjectPtr obj) {
|
||||
if (!obj->IsWeakSerializationReference()) return obj->GetClassId();
|
||||
return TargetClassIdOf(WeakSerializationReference::RawCast(obj));
|
||||
}
|
||||
static ObjectPtr Unwrap(const Object& obj) { return Unwrap(obj.ptr()); }
|
||||
static ObjectPtr UnwrapIfTarget(ObjectPtr obj) { return Unwrap(obj); }
|
||||
static ObjectPtr UnwrapIfTarget(const Object& obj) { return Unwrap(obj); }
|
||||
|
||||
static intptr_t InstanceSize() {
|
||||
return RoundedAllocationSize(sizeof(UntaggedWeakSerializationReference));
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
// Returns true if a new WSR would be created when calling Wrap.
|
||||
static bool CanWrap(const Object& object);
|
||||
|
||||
// This returns ObjectPtr, not WeakSerializationReferencePtr, because
|
||||
// target.ptr() is returned when CanWrap(target) is false.
|
||||
static ObjectPtr Wrap(Zone* zone, const Object& target);
|
||||
#endif
|
||||
static WeakSerializationReferencePtr New(const Object& target,
|
||||
const Object& replacement);
|
||||
|
||||
private:
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(WeakSerializationReference, Object);
|
||||
@@ -6294,17 +6239,21 @@ class Code : public Object {
|
||||
// while generating the snapshot.
|
||||
FunctionPtr function() const {
|
||||
ASSERT(IsFunctionCode());
|
||||
return Function::RawCast(
|
||||
WeakSerializationReference::Unwrap(untag()->owner()));
|
||||
return Function::RawCast(owner());
|
||||
}
|
||||
|
||||
ObjectPtr owner() const { return untag()->owner(); }
|
||||
ObjectPtr owner() const {
|
||||
return WeakSerializationReference::Unwrap(untag()->owner());
|
||||
}
|
||||
void set_owner(const Object& owner) const;
|
||||
|
||||
classid_t OwnerClassId() const { return OwnerClassIdOf(ptr()); }
|
||||
static classid_t OwnerClassIdOf(CodePtr raw) {
|
||||
return WeakSerializationReference::UnwrappedClassIdOf(
|
||||
raw->untag()->owner());
|
||||
ObjectPtr owner = WeakSerializationReference::Unwrap(raw->untag()->owner());
|
||||
if (!owner->IsHeapObject()) {
|
||||
return RawSmiValue(static_cast<SmiPtr>(owner));
|
||||
}
|
||||
return owner->GetClassId();
|
||||
}
|
||||
|
||||
static intptr_t owner_offset() { return OFFSET_OF(UntaggedCode, owner_); }
|
||||
|
||||
@@ -536,6 +536,7 @@ REGULAR_VISITOR(UserTag)
|
||||
REGULAR_VISITOR(SubtypeTestCache)
|
||||
REGULAR_VISITOR(LoadingUnit)
|
||||
REGULAR_VISITOR(KernelProgramInfo)
|
||||
REGULAR_VISITOR(WeakSerializationReference)
|
||||
VARIABLE_VISITOR(TypeArguments, Smi::Value(raw_obj->untag()->length_))
|
||||
VARIABLE_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
|
||||
VARIABLE_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries_)
|
||||
@@ -576,11 +577,6 @@ UNREACHABLE_VISITOR(String)
|
||||
UNREACHABLE_VISITOR(FutureOr)
|
||||
// Smi has no heap representation.
|
||||
UNREACHABLE_VISITOR(Smi)
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
NULL_VISITOR(WeakSerializationReference)
|
||||
#else
|
||||
REGULAR_VISITOR(WeakSerializationReference)
|
||||
#endif
|
||||
|
||||
intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj,
|
||||
ObjectPointerVisitor* visitor) {
|
||||
|
||||
@@ -1508,14 +1508,10 @@ class UntaggedKernelProgramInfo : public UntaggedObject {
|
||||
class UntaggedWeakSerializationReference : public UntaggedObject {
|
||||
RAW_HEAP_OBJECT_IMPLEMENTATION(WeakSerializationReference);
|
||||
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
VISIT_NOTHING();
|
||||
ClassIdTagType cid_;
|
||||
#else
|
||||
VISIT_FROM(ObjectPtr, target)
|
||||
POINTER_FIELD(ObjectPtr, target)
|
||||
VISIT_TO(ObjectPtr, target)
|
||||
#endif
|
||||
POINTER_FIELD(ObjectPtr, replacement)
|
||||
VISIT_TO(ObjectPtr, replacement)
|
||||
};
|
||||
|
||||
class UntaggedCode : public UntaggedObject {
|
||||
|
||||
@@ -84,6 +84,8 @@ namespace dart {
|
||||
F(KernelProgramInfo, libraries_cache_) \
|
||||
F(KernelProgramInfo, classes_cache_) \
|
||||
F(KernelProgramInfo, retained_kernel_blob_) \
|
||||
F(WeakSerializationReference, target_) \
|
||||
F(WeakSerializationReference, replacement_) \
|
||||
F(Code, object_pool_) \
|
||||
F(Code, instructions_) \
|
||||
F(Code, owner_) \
|
||||
@@ -192,7 +194,7 @@ namespace dart {
|
||||
F(TypedDataView, offset_in_bytes_) \
|
||||
F(FutureOr, type_arguments_)
|
||||
|
||||
#define AOT_CLASSES_AND_FIELDS(F) F(WeakSerializationReference, cid_)
|
||||
#define AOT_CLASSES_AND_FIELDS(F)
|
||||
|
||||
#define JIT_CLASSES_AND_FIELDS(F) \
|
||||
F(Code, active_instructions_) \
|
||||
@@ -201,7 +203,6 @@ namespace dart {
|
||||
F(ICData, receivers_static_type_) \
|
||||
F(Function, unoptimized_code_) \
|
||||
F(Field, type_test_cache_) \
|
||||
F(WeakSerializationReference, target_)
|
||||
|
||||
#define NON_PRODUCT_CLASSES_AND_FIELDS(F) \
|
||||
F(ReceivePort, debug_name_) \
|
||||
|
||||
@@ -321,7 +321,10 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
||||
FunctionPtr StackFrame::LookupDartFunction() const {
|
||||
const Code& code = Code::Handle(LookupDartCode());
|
||||
if (!code.IsNull()) {
|
||||
return code.function();
|
||||
const Object& owner = Object::Handle(code.owner());
|
||||
if (owner.IsFunction()) {
|
||||
return Function::Cast(owner).ptr();
|
||||
}
|
||||
}
|
||||
return Function::null();
|
||||
}
|
||||
|
||||
@@ -293,6 +293,7 @@ class ObjectPointerVisitor;
|
||||
V(UnwindError, "UnwindError") \
|
||||
V(Value, "value") \
|
||||
V(Values, "values") \
|
||||
V(WeakSerializationReference, "WeakSerializationReference") \
|
||||
V(YieldKw, "yield") \
|
||||
V(_AsyncAwaitStart, "start") \
|
||||
V(_AsyncStarStreamController, "_AsyncStarStreamController") \
|
||||
|
||||
Reference in New Issue
Block a user