[vm] Extend the hash_table.h templates to support weak sets.

Make the canonical string table weak.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/50648
Change-Id: I04d84a917bd71469d43483cefba8165628b9a63f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278673
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2023-01-17 21:45:02 +00:00 committed by Commit Queue
parent 40630c2470
commit a1dd92d345
13 changed files with 331 additions and 48 deletions

View file

@ -624,7 +624,7 @@ class CanonicalSetDeserializationCluster : public DeserializationCluster {
const char* name)
: DeserializationCluster(name, is_canonical),
is_root_unit_(is_root_unit),
table_(Array::Handle()) {}
table_(SetType::ArrayHandle::Handle()) {}
void BuildCanonicalSetFromLayout(Deserializer* d) {
if (!is_root_unit_ || !is_canonical()) {
@ -645,11 +645,11 @@ class CanonicalSetDeserializationCluster : public DeserializationCluster {
protected:
const bool is_root_unit_;
intptr_t first_element_;
Array& table_;
typename SetType::ArrayHandle& table_;
void VerifyCanonicalSet(Deserializer* d,
const Array& refs,
const Array& current_table) {
const typename SetType::ArrayHandle& current_table) {
#if defined(DEBUG)
// First check that we are not overwriting a table and loosing information.
if (!current_table.IsNull()) {
@ -672,7 +672,7 @@ class CanonicalSetDeserializationCluster : public DeserializationCluster {
private:
struct DeserializationFinger {
ArrayPtr table;
typename SetType::ArrayPtr table;
intptr_t current_index;
ObjectPtr gap_element;
@ -687,12 +687,12 @@ class CanonicalSetDeserializationCluster : public DeserializationCluster {
table->untag()->data()[current_index++] = object;
}
ArrayPtr Finish() {
if (table != Array::null()) {
typename SetType::ArrayPtr Finish() {
if (table != SetType::ArrayHandle::null()) {
FillGap(Smi::Value(table->untag()->length()) - current_index);
}
auto result = table;
table = Array::null();
table = SetType::ArrayHandle::null();
return result;
}
};
@ -700,11 +700,12 @@ class CanonicalSetDeserializationCluster : public DeserializationCluster {
static DeserializationFinger StartDeserialization(Deserializer* d,
intptr_t length,
intptr_t count) {
const intptr_t instance_size = Array::InstanceSize(length);
ArrayPtr table = static_cast<ArrayPtr>(
const intptr_t instance_size = SetType::ArrayHandle::InstanceSize(length);
typename SetType::ArrayPtr table = static_cast<typename SetType::ArrayPtr>(
d->heap()->old_space()->AllocateSnapshot(instance_size));
Deserializer::InitializeHeader(table, kArrayCid, instance_size);
table->untag()->type_arguments_ = TypeArguments::null();
Deserializer::InitializeHeader(table, SetType::Storage::ArrayCid,
instance_size);
InitTypeArgsOrNext(table);
table->untag()->length_ = Smi::New(length);
for (intptr_t i = 0; i < SetType::kFirstKeyIndex; i++) {
table->untag()->data()[i] = Smi::New(0);
@ -712,6 +713,13 @@ class CanonicalSetDeserializationCluster : public DeserializationCluster {
table->untag()->data()[SetType::kOccupiedEntriesIndex] = Smi::New(count);
return {table, SetType::kFirstKeyIndex, SetType::UnusedMarker().ptr()};
}
static void InitTypeArgsOrNext(ArrayPtr table) {
table->untag()->type_arguments_ = TypeArguments::null();
}
static void InitTypeArgsOrNext(WeakArrayPtr table) {
table->untag()->next_seen_by_gc_ = WeakArray::null();
}
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@ -3065,7 +3073,8 @@ class RODataDeserializationCluster
void PostLoad(Deserializer* d, const Array& refs, bool primary) {
if (!table_.IsNull()) {
auto object_store = d->isolate_group()->object_store();
VerifyCanonicalSet(d, refs, Array::Handle(object_store->symbol_table()));
VerifyCanonicalSet(d, refs,
WeakArray::Handle(object_store->symbol_table()));
object_store->set_symbol_table(table_);
if (d->isolate_group() == Dart::vm_isolate_group()) {
Symbols::InitFromSnapshot(d->isolate_group());
@ -5501,6 +5510,8 @@ class WeakPropertySerializationCluster : public SerializationCluster {
void Trace(Serializer* s, ObjectPtr object) {
WeakPropertyPtr property = WeakProperty::RawCast(object);
objects_.Add(property);
s->PushWeak(property->untag()->key());
}
void RetraceEphemerons(Serializer* s) {
@ -5857,6 +5868,92 @@ class ArrayDeserializationCluster
const intptr_t cid_;
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class WeakArraySerializationCluster : public SerializationCluster {
public:
WeakArraySerializationCluster()
: SerializationCluster("WeakArray", kWeakArrayCid, kSizeVaries) {}
~WeakArraySerializationCluster() {}
void Trace(Serializer* s, ObjectPtr object) {
WeakArrayPtr array = WeakArray::RawCast(object);
objects_.Add(array);
const intptr_t length = Smi::Value(array->untag()->length());
for (intptr_t i = 0; i < length; i++) {
s->PushWeak(array->untag()->element(i));
}
}
void WriteAlloc(Serializer* s) {
const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
WeakArrayPtr array = objects_[i];
s->AssignRef(array);
AutoTraceObject(array);
const intptr_t length = Smi::Value(array->untag()->length());
s->WriteUnsigned(length);
target_memory_size_ += compiler::target::WeakArray::InstanceSize(length);
}
}
void WriteFill(Serializer* s) {
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
WeakArrayPtr array = objects_[i];
AutoTraceObject(array);
const intptr_t length = Smi::Value(array->untag()->length());
s->WriteUnsigned(length);
for (intptr_t j = 0; j < length; j++) {
if (s->HasRef(array->untag()->element(j))) {
s->WriteElementRef(array->untag()->element(j), j);
} else {
s->WriteElementRef(Object::null(), j);
}
}
}
}
private:
GrowableArray<WeakArrayPtr> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
class WeakArrayDeserializationCluster : public DeserializationCluster {
public:
WeakArrayDeserializationCluster() : DeserializationCluster("WeakArray") {}
~WeakArrayDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
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++) {
const intptr_t length = d->ReadUnsigned();
d->AssignRef(
old_space->AllocateSnapshot(WeakArray::InstanceSize(length)));
}
stop_index_ = d->next_index();
}
void ReadFill(Deserializer* d_, bool primary) {
Deserializer::Local d(d_);
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
WeakArrayPtr array = static_cast<WeakArrayPtr>(d.Ref(id));
const intptr_t length = d.ReadUnsigned();
Deserializer::InitializeHeader(array, kWeakArrayCid,
WeakArray::InstanceSize(length), false);
array->untag()->next_seen_by_gc_ = WeakArray::null();
array->untag()->length_ = Smi::New(length);
for (intptr_t j = 0; j < length; j++) {
array->untag()->data()[j] = d.ReadRef();
}
}
}
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class StringSerializationCluster
: public CanonicalSetSerializationCluster<CanonicalStringSet,
@ -6019,7 +6116,8 @@ class StringDeserializationCluster
void PostLoad(Deserializer* d, const Array& refs, bool primary) {
if (!table_.IsNull()) {
auto object_store = d->isolate_group()->object_store();
VerifyCanonicalSet(d, refs, Array::Handle(object_store->symbol_table()));
VerifyCanonicalSet(d, refs,
WeakArray::Handle(object_store->symbol_table()));
object_store->set_symbol_table(table_);
if (d->isolate_group() == Dart::vm_isolate_group()) {
Symbols::InitFromSnapshot(d->isolate_group());
@ -6055,7 +6153,8 @@ class FakeSerializationCluster : public SerializationCluster {
#if !defined(DART_PRECOMPILED_RUNTIME)
class VMSerializationRoots : public SerializationRoots {
public:
explicit VMSerializationRoots(const Array& symbols, bool should_write_symbols)
explicit VMSerializationRoots(const WeakArray& symbols,
bool should_write_symbols)
: symbols_(symbols),
should_write_symbols_(should_write_symbols),
zone_(Thread::Current()->zone()) {}
@ -6174,7 +6273,7 @@ class VMSerializationRoots : public SerializationRoots {
}
private:
const Array& symbols_;
const WeakArray& symbols_;
const bool should_write_symbols_;
Zone* zone_;
};
@ -6182,7 +6281,7 @@ class VMSerializationRoots : public SerializationRoots {
class VMDeserializationRoots : public DeserializationRoots {
public:
VMDeserializationRoots() : symbol_table_(Array::Handle()) {}
VMDeserializationRoots() : symbol_table_(WeakArray::Handle()) {}
bool AddBaseObjects(Deserializer* d) {
// These objects are always allocated by Object::InitOnce, so they are not
@ -6267,7 +6366,7 @@ class VMDeserializationRoots : public DeserializationRoots {
}
private:
Array& symbol_table_;
WeakArray& symbol_table_;
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@ -6288,7 +6387,7 @@ static const char* const kObjectStoreFieldNames[] = {
class ProgramSerializationRoots : public SerializationRoots {
public:
#define RESET_ROOT_LIST(V) \
V(symbol_table, Array, HashTables::New<CanonicalStringSet>(4)) \
V(symbol_table, WeakArray, HashTables::New<CanonicalStringSet>(4)) \
V(canonical_types, Array, HashTables::New<CanonicalTypeSet>(4)) \
V(canonical_function_types, Array, \
HashTables::New<CanonicalFunctionTypeSet>(4)) \
@ -7196,6 +7295,8 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid,
case kImmutableArrayCid:
return new (Z)
ArraySerializationCluster(is_canonical, kImmutableArrayCid);
case kWeakArrayCid:
return new (Z) WeakArraySerializationCluster();
case kStringCid:
return new (Z) StringSerializationCluster(
is_canonical, cluster_represents_canonical_set && !vm_);
@ -7641,6 +7742,18 @@ void Serializer::Push(ObjectPtr object, intptr_t cid_override) {
}
}
void Serializer::PushWeak(ObjectPtr object) {
// The GC considers immediate objects to always be alive. This doesn't happen
// automatically in the serializer because the serializer does not have
// immediate objects: it handles Smis as ref indices like all other objects.
// This visit causes the serializer to reproduce the GC's semantics for
// weakness, which in particular allows the templates in hash_table.h to work
// with weak arrays because the metadata Smis always survive.
if (!object->IsHeapObject() || vm_) {
Push(object);
}
}
void Serializer::Trace(ObjectPtr object, intptr_t cid_override) {
intptr_t cid;
bool is_canonical;
@ -8366,6 +8479,8 @@ DeserializationCluster* Deserializer::ReadCluster() {
case kImmutableArrayCid:
return new (Z)
ArrayDeserializationCluster(is_canonical, kImmutableArrayCid);
case kWeakArrayCid:
return new (Z) WeakArrayDeserializationCluster();
case kStringCid:
return new (Z) StringDeserializationCluster(
is_canonical,
@ -8857,7 +8972,8 @@ ZoneGrowableArray<Object*>* FullSnapshotWriter::WriteVMSnapshot() {
serializer.ReserveHeader();
serializer.WriteVersionAndFeatures(true);
VMSerializationRoots roots(
Array::Handle(Dart::vm_isolate_group()->object_store()->symbol_table()),
WeakArray::Handle(
Dart::vm_isolate_group()->object_store()->symbol_table()),
/*should_write_symbols=*/!Snapshot::IncludesStringsInROData(kind_));
ZoneGrowableArray<Object*>* objects = serializer.Serialize(&roots);
serializer.FillHeader(serializer.kind());

View file

@ -233,6 +233,7 @@ class Serializer : public ThreadStackResource {
intptr_t GetCodeIndex(CodePtr code);
void Push(ObjectPtr object, intptr_t cid_override = kIllegalCid);
void PushWeak(ObjectPtr object);
void AddUntracedRef() { num_written_objects_++; }

View file

@ -132,7 +132,8 @@ class SymbolTraits {
}
};
typedef UnorderedHashSet<SymbolTraits, AcqRelStorageTraits> CanonicalStringSet;
typedef UnorderedHashSet<SymbolTraits, WeakAcqRelStorageTraits>
CanonicalStringSet;
class CanonicalTypeKey {
public:

View file

@ -972,11 +972,8 @@ bool AotCallSpecializer::TryExpandCallThroughGetter(const Class& receiver_class,
Function& target = Function::Handle(Z);
const String& getter_name = String::ZoneHandle(
Z, Symbols::LookupFromGet(thread(), call->function_name()));
if (getter_name.IsNull()) {
return false;
}
const String& getter_name =
String::ZoneHandle(Z, Symbols::FromGet(thread(), call->function_name()));
const Array& args_desc_array = Array::Handle(
Z,

View file

@ -1425,7 +1425,10 @@ class WeakSerializationReference : public AllStatic {
class WeakArray : public AllStatic {
public:
static word InstanceSize() { return 0; }
static word length_offset();
static word element_offset(intptr_t index);
static word InstanceSize(intptr_t length);
static word InstanceSize();
FINAL_CLASS();
};

View file

@ -57,6 +57,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
12;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65533;
@ -730,6 +733,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
24;
static constexpr dart::compiler::target::word WeakArray_element_size = 8;
static constexpr dart::compiler::target::word Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
@ -1414,6 +1420,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
12;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65533;
@ -2087,6 +2096,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
24;
static constexpr dart::compiler::target::word WeakArray_element_size = 8;
static constexpr dart::compiler::target::word Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
@ -2772,6 +2784,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
16;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65532;
@ -3454,6 +3469,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
16;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65532;
@ -4137,6 +4155,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
12;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65533;
@ -4812,6 +4833,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
24;
static constexpr dart::compiler::target::word WeakArray_element_size = 8;
static constexpr dart::compiler::target::word Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
@ -5496,6 +5520,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
12;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65533;
@ -6161,6 +6188,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
24;
static constexpr dart::compiler::target::word WeakArray_element_size = 8;
static constexpr dart::compiler::target::word Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
@ -6837,6 +6867,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
12;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65533;
@ -7502,6 +7535,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
24;
static constexpr dart::compiler::target::word WeakArray_element_size = 8;
static constexpr dart::compiler::target::word Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
@ -8179,6 +8215,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
16;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65532;
@ -8853,6 +8892,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
16;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65532;
@ -9528,6 +9570,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
12;
static constexpr dart::compiler::target::word WeakArray_element_size = 4;
static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
65533;
@ -10195,6 +10240,9 @@ static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
static constexpr dart::compiler::target::word
TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word TwoByteString_element_size = 2;
static constexpr dart::compiler::target::word WeakArray_elements_start_offset =
24;
static constexpr dart::compiler::target::word WeakArray_element_size = 8;
static constexpr dart::compiler::target::word Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
@ -10880,6 +10928,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -11629,6 +11680,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 24;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 8;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -12386,6 +12440,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 24;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 8;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -13141,6 +13198,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -13896,6 +13956,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -14652,6 +14715,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -15403,6 +15469,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 24;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 8;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -16157,6 +16226,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -16897,6 +16969,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 24;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 8;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -17645,6 +17720,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 24;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 8;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -18391,6 +18469,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -19137,6 +19218,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -19884,6 +19968,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 12;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 4;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
268435455;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
@ -20626,6 +20713,9 @@ static constexpr dart::compiler::target::word
AOT_TwoByteString_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_element_size =
2;
static constexpr dart::compiler::target::word
AOT_WeakArray_elements_start_offset = 24;
static constexpr dart::compiler::target::word AOT_WeakArray_element_size = 8;
static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
576460752303423487;
static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =

View file

@ -62,6 +62,7 @@
ARRAY(Record, field_offset) \
ARRAY(TypeArguments, type_at_offset) \
ARRAY(TwoByteString, element_offset) \
ARRAY(WeakArray, element_offset) \
ARRAY_SIZEOF(Array, InstanceSize, element_offset) \
ARRAY_SIZEOF(Code, InstanceSize, element_offset) \
ARRAY_SIZEOF(Context, InstanceSize, variable_offset) \
@ -72,6 +73,7 @@
ARRAY_SIZEOF(Record, InstanceSize, field_offset) \
ARRAY_SIZEOF(TypeArguments, InstanceSize, type_at_offset) \
ARRAY_SIZEOF(TwoByteString, InstanceSize, element_offset) \
ARRAY_SIZEOF(WeakArray, InstanceSize, element_offset) \
CONSTANT(Array, kMaxElements) \
CONSTANT(Array, kMaxNewSpaceElements) \
CONSTANT(Context, kMaxElements) \

View file

@ -15,6 +15,7 @@ namespace dart {
struct ArrayStorageTraits {
using ArrayHandle = Array;
using ArrayPtr = dart::ArrayPtr;
static const intptr_t ArrayCid = kArrayCid;
static ArrayHandle& PtrToHandle(ArrayPtr ptr) { return Array::Handle(ptr); }
@ -43,6 +44,40 @@ struct ArrayStorageTraits {
}
};
struct WeakArrayStorageTraits {
using ArrayHandle = WeakArray;
using ArrayPtr = dart::WeakArrayPtr;
static const intptr_t ArrayCid = kWeakArrayCid;
static ArrayHandle& PtrToHandle(ArrayPtr ptr) {
return WeakArray::Handle(ptr);
}
static void SetHandle(ArrayHandle& dst, const ArrayHandle& src) { // NOLINT
dst = src.ptr();
}
static void ClearHandle(ArrayHandle& handle) { // NOLINT
handle = WeakArray::null();
}
static ArrayPtr New(Zone* zone, intptr_t length, Heap::Space space) {
return WeakArray::New(length, space);
}
static bool IsImmutable(const ArrayHandle& handle) {
return handle.ptr()->untag()->InVMIsolateHeap();
}
static ObjectPtr At(ArrayHandle* array, intptr_t index) {
return array->At(index);
}
static void SetAt(ArrayHandle* array, intptr_t index, const Object& value) {
array->SetAt(index, value);
}
};
struct AcqRelStorageTraits : ArrayStorageTraits {
static ObjectPtr At(ArrayHandle* array, intptr_t index) {
return array->AtAcquire(index);
@ -53,10 +88,20 @@ struct AcqRelStorageTraits : ArrayStorageTraits {
}
};
struct WeakAcqRelStorageTraits : WeakArrayStorageTraits {
static ObjectPtr At(ArrayHandle* array, intptr_t index) {
return array->AtAcquire(index);
}
static void SetAt(ArrayHandle* array, intptr_t index, const Object& value) {
array->SetAtRelease(index, value);
}
};
class HashTableBase : public ValueObject {
public:
static const Object& UnusedMarker() { return Object::transition_sentinel(); }
static const Object& DeletedMarker() { return Object::sentinel(); }
static const Object& DeletedMarker() { return Object::null_object(); }
};
// OVERVIEW:
@ -206,9 +251,6 @@ class HashTable : public HashTableBase {
template <typename Key>
intptr_t FindKey(const Key& key) const {
const intptr_t num_entries = NumEntries();
// 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);
@ -244,9 +286,6 @@ class HashTable : public HashTableBase {
bool FindKeyOrDeletedOrUnused(const Key& key, intptr_t* entry) const {
const intptr_t num_entries = NumEntries();
ASSERT(entry != NULL);
// 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));
@ -294,9 +333,6 @@ class HashTable : public HashTableBase {
}
InternalSetKey(entry, key);
ASSERT(IsOccupied(entry));
// Deleted may undercount due to weak references used during AOT
// snapshotting.
NOT_IN_PRECOMPILED(ASSERT(NumOccupied() < NumEntries()));
}
bool IsUnused(intptr_t entry) const {
@ -401,6 +437,26 @@ class HashTable : public HashTableBase {
}
#endif // !PRODUCT
void UpdateWeakDeleted() const {
if (StorageTraits::ArrayCid != kWeakArrayCid) return;
// As entries are deleted by GC, NumOccupied and NumDeleted become stale.
// Re-count before growing/rehashing to prevent table growth when the
// number of live entries is not increasing.
intptr_t num_occupied = 0;
intptr_t num_deleted = 0;
for (intptr_t i = 0, n = NumEntries(); i < n; i++) {
if (IsDeleted(i)) {
num_deleted++;
}
if (IsOccupied(i)) {
num_occupied++;
}
}
SetSmiValueAt(kOccupiedEntriesIndex, num_occupied);
SetSmiValueAt(kDeletedEntriesIndex, num_deleted);
}
protected:
static const intptr_t kOccupiedEntriesIndex = 0;
static const intptr_t kDeletedEntriesIndex = 1;
@ -439,6 +495,9 @@ class HashTable : public HashTableBase {
intptr_t GetSmiValueAt(intptr_t index) const {
ASSERT(!data_->IsNull());
if (StorageTraits::At(data_, index)->IsHeapObject()) {
Object::Handle(StorageTraits::At(data_, index)).Print();
}
ASSERT(!StorageTraits::At(data_, index)->IsHeapObject());
return Smi::Value(Smi::RawCast(StorageTraits::At(data_, index)));
}
@ -476,11 +535,13 @@ class UnorderedHashTable
: public HashTable<KeyTraits, kUserPayloadSize, 0, StorageTraits> {
public:
typedef HashTable<KeyTraits, kUserPayloadSize, 0, StorageTraits> BaseTable;
typedef typename StorageTraits::ArrayPtr ArrayPtr;
typedef typename StorageTraits::ArrayHandle ArrayHandle;
static const intptr_t kPayloadSize = kUserPayloadSize;
explicit UnorderedHashTable(ArrayPtr data)
: BaseTable(Thread::Current()->zone(), data) {}
UnorderedHashTable(Zone* zone, ArrayPtr data) : BaseTable(zone, data) {}
UnorderedHashTable(Object* key, Smi* value, Array* data)
UnorderedHashTable(Object* key, Smi* value, ArrayHandle* data)
: BaseTable(key, value, data) {}
// Note: Does not check for concurrent modification.
class Iterator {
@ -565,6 +626,9 @@ class HashTables : public AllStatic {
if (current < high && !too_many_deleted) {
return;
}
table.UpdateWeakDeleted();
// Normally we double the size here, but if less than half are occupied
// then it won't grow (this would imply that there were quite a lot of
// deleted slots). We don't want to constantly rehash if we are adding
@ -724,13 +788,15 @@ class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > {
: BaseMap(key, value, data) {}
};
template <typename BaseIterTable>
template <typename BaseIterTable, typename StorageTraits>
class HashSet : public BaseIterTable {
public:
typedef typename StorageTraits::ArrayPtr ArrayPtr;
typedef typename StorageTraits::ArrayHandle ArrayHandle;
explicit HashSet(ArrayPtr data)
: BaseIterTable(Thread::Current()->zone(), data) {}
HashSet(Zone* zone, ArrayPtr data) : BaseIterTable(zone, data) {}
HashSet(Object* key, Smi* value, Array* data)
HashSet(Object* key, Smi* value, ArrayHandle* data)
: BaseIterTable(key, value, data) {}
bool Insert(const Object& key) {
EnsureCapacity();
@ -800,17 +866,20 @@ class HashSet : public BaseIterTable {
template <typename KeyTraits, typename TableStorageTraits = ArrayStorageTraits>
class UnorderedHashSet
: public HashSet<UnorderedHashTable<KeyTraits, 0, TableStorageTraits>> {
: public HashSet<UnorderedHashTable<KeyTraits, 0, TableStorageTraits>,
TableStorageTraits> {
using UnderlyingTable = UnorderedHashTable<KeyTraits, 0, TableStorageTraits>;
public:
typedef HashSet<UnderlyingTable> BaseSet;
typedef HashSet<UnderlyingTable, TableStorageTraits> BaseSet;
typedef typename TableStorageTraits::ArrayPtr ArrayPtr;
typedef typename TableStorageTraits::ArrayHandle ArrayHandle;
explicit UnorderedHashSet(ArrayPtr data)
: BaseSet(Thread::Current()->zone(), data) {
ASSERT(data != Array::null());
ASSERT(data != Object::null());
}
UnorderedHashSet(Zone* zone, ArrayPtr data) : BaseSet(zone, data) {}
UnorderedHashSet(Object* key, Smi* value, Array* data)
UnorderedHashSet(Object* key, Smi* value, ArrayHandle* data)
: BaseSet(key, value, data) {}
void Dump() const {

View file

@ -2847,6 +2847,7 @@ void MessageSerializer::Trace(Object* object) {
ILLEGAL(UserTag)
ILLEGAL(WeakProperty)
ILLEGAL(WeakReference)
ILLEGAL(WeakArray)
// From "dart:ffi" we handle only Pointer/DynamicLibrary specially, since
// those are the only non-abstract classes (so we avoid checking more cids

View file

@ -139,7 +139,7 @@ class ObjectPointerVisitor;
RW(Class, finalizer_class) \
RW(Class, finalizer_entry_class) \
RW(Class, native_finalizer_class) \
ARW_AR(Array, symbol_table) \
ARW_AR(WeakArray, symbol_table) \
RW(Array, canonical_types) \
RW(Array, canonical_function_types) \
RW(Array, canonical_record_types) \

View file

@ -112,6 +112,8 @@ REUSABLE_HANDLE_LIST(REUSABLE_SCOPE)
ReusableTypeArgumentsHandleScope reused_type_arguments_handle(thread);
#define REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread) \
ReusableTypeParameterHandleScope reused_type_parameter(thread);
#define REUSABLE_WEAK_ARRAY_HANDLESCOPE(thread) \
ReusableWeakArrayHandleScope reused_weak_array(thread);
} // namespace dart

View file

@ -173,7 +173,7 @@ void Symbols::SetupSymbolTable(IsolateGroup* isolate_group) {
const intptr_t initial_size = (isolate_group == Dart::vm_isolate_group())
? kInitialVMIsolateSymtabSize
: kInitialSymtabSize;
Array& array = Array::Handle(
class WeakArray& array = WeakArray::Handle(
HashTables::New<CanonicalStringSet>(initial_size, Heap::kOld));
isolate_group->object_store()->set_symbol_table(array);
}
@ -341,7 +341,7 @@ StringPtr Symbols::NewSymbol(Thread* thread, const StringType& str) {
String& symbol = String::Handle(thread->zone());
dart::Object& key = thread->ObjectHandle();
Smi& value = thread->SmiHandle();
Array& data = thread->ArrayHandle();
class WeakArray& data = thread->WeakArrayHandle();
{
auto vm_isolate_group = Dart::vm_isolate_group();
data = vm_isolate_group->object_store()->symbol_table();
@ -386,7 +386,7 @@ StringPtr Symbols::Lookup(Thread* thread, const StringType& str) {
String& symbol = String::Handle(thread->zone());
dart::Object& key = thread->ObjectHandle();
Smi& value = thread->SmiHandle();
Array& data = thread->ArrayHandle();
class WeakArray& data = thread->WeakArrayHandle();
{
auto vm_isolate_group = Dart::vm_isolate_group();
data = vm_isolate_group->object_store()->symbol_table();

View file

@ -92,7 +92,8 @@ class Thread;
V(String) \
V(TypeParameters) \
V(TypeArguments) \
V(TypeParameter)
V(TypeParameter) \
V(WeakArray)
#define CACHED_VM_STUBS_LIST(V) \
V(CodePtr, fix_callers_target_code_, StubCode::FixCallersTarget().ptr(), \