mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 01:45:06 +00:00
[vm] Extend the hash_table.h templates to support weak sets.
Make the canonical string table weak. Remove incorrect assumption that a symbol not already existing implies there is no target. This would be true but for all the call-through-field/method-extractor nonsense. TEST=ci Bug: https://github.com/dart-lang/sdk/issues/50648 Bug: b/265897936 Change-Id: I463807a5d8c064888abbdc3dc75e916c2bdc8fa5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279273 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
68c32274c7
commit
49a135ab7e
|
@ -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());
|
||||
|
|
|
@ -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_++; }
|
||||
|
||||
|
|
|
@ -132,7 +132,8 @@ class SymbolTraits {
|
|||
}
|
||||
};
|
||||
|
||||
typedef UnorderedHashSet<SymbolTraits, AcqRelStorageTraits> CanonicalStringSet;
|
||||
typedef UnorderedHashSet<SymbolTraits, WeakAcqRelStorageTraits>
|
||||
CanonicalStringSet;
|
||||
|
||||
class CanonicalTypeKey {
|
||||
public:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1719,12 +1719,8 @@ void Precompiler::CheckForNewDynamicFunctions() {
|
|||
functions_called_dynamically_.Insert(function2);
|
||||
}
|
||||
} else if (function.kind() == UntaggedFunction::kRegularFunction) {
|
||||
selector2 = Field::LookupGetterSymbol(selector);
|
||||
selector3 = String::null();
|
||||
if (!selector2.IsNull()) {
|
||||
selector3 =
|
||||
Function::CreateDynamicInvocationForwarderName(selector2);
|
||||
}
|
||||
selector2 = Field::GetterSymbol(selector);
|
||||
selector3 = Function::CreateDynamicInvocationForwarderName(selector2);
|
||||
if (IsSent(selector2) || IsSent(selector3)) {
|
||||
metadata = kernel::ProcedureAttributesOf(function, Z);
|
||||
found_metadata = true;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -93,7 +93,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(), \
|
||||
|
|
Loading…
Reference in a new issue