Index: runtime/vm/hash_table.h |
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h |
index 15317a17fa45d720af013076fb89fe779e63d276..8408f23e2eb12b8feb97b8a92b4e009419f3c309 100644 |
--- a/runtime/vm/hash_table.h |
+++ b/runtime/vm/hash_table.h |
@@ -85,23 +85,21 @@ template<typename KeyTraits, intptr_t kPayloadSize, intptr_t kMetaDataSize> |
class HashTable : public ValueObject { |
public: |
typedef KeyTraits Traits; |
+ // Uses the passed in handles for all handle operations. |
+ // 'Release' must be called at the end to obtain the final table |
+ // after potential growth/shrinkage. |
+ HashTable(Object* key, Smi* index, Array* data) |
+ : key_handle_(key), |
+ smi_handle_(index), |
+ data_(data), |
+ released_data_(NULL) {} |
// Uses 'zone' for handle allocation. 'Release' must be called at the end |
// to obtain the final table after potential growth/shrinkage. |
HashTable(Zone* zone, RawArray* data) |
- : zone_(zone), |
- key_handle_(Object::Handle(zone_)), |
- smi_handle_(Smi::Handle(zone_)), |
- data_(&Array::Handle(zone_, data)), |
+ : key_handle_(&Object::Handle(zone)), |
+ smi_handle_(&Smi::Handle(zone)), |
+ data_(&Array::Handle(zone, data)), |
released_data_(NULL) {} |
- // Like above, except uses current zone. |
- explicit HashTable(RawArray* data) |
- : zone_(Thread::Current()->zone()), |
- key_handle_(Object::Handle(zone_)), |
- smi_handle_(Smi::Handle(zone_)), |
- data_(&Array::Handle(zone_, data)), |
- released_data_(NULL) { |
- ASSERT(!data_->IsNull()); |
- } |
// Returns the final table. The handle is cleared when this HashTable is |
// destroyed. |
@@ -134,15 +132,15 @@ class HashTable : public ValueObject { |
// Initializes an empty table. |
void Initialize() const { |
ASSERT(data_->Length() >= ArrayLengthForNumOccupied(0)); |
- smi_handle_ = Smi::New(0); |
- data_->SetAt(kOccupiedEntriesIndex, smi_handle_); |
- data_->SetAt(kDeletedEntriesIndex, smi_handle_); |
+ *smi_handle_ = Smi::New(0); |
+ data_->SetAt(kOccupiedEntriesIndex, *smi_handle_); |
+ data_->SetAt(kDeletedEntriesIndex, *smi_handle_); |
NOT_IN_PRODUCT( |
- data_->SetAt(kNumGrowsIndex, smi_handle_); |
- data_->SetAt(kNumLT5LookupsIndex, smi_handle_); |
- data_->SetAt(kNumLT25LookupsIndex, smi_handle_); |
- data_->SetAt(kNumGT25LookupsIndex, smi_handle_); |
+ data_->SetAt(kNumGrowsIndex, *smi_handle_); |
+ data_->SetAt(kNumLT5LookupsIndex, *smi_handle_); |
+ data_->SetAt(kNumLT25LookupsIndex, *smi_handle_); |
+ data_->SetAt(kNumGT25LookupsIndex, *smi_handle_); |
) // !PRODUCT |
for (intptr_t i = kHeaderSize; i < data_->Length(); ++i) { |
@@ -171,8 +169,8 @@ NOT_IN_PRODUCT( |
NOT_IN_PRODUCT(UpdateCollisions(collisions);) |
return -1; |
} else if (!IsDeleted(probe)) { |
- key_handle_ = GetKey(probe); |
- if (KeyTraits::IsMatch(key, key_handle_)) { |
+ *key_handle_ = GetKey(probe); |
+ if (KeyTraits::IsMatch(key, *key_handle_)) { |
NOT_IN_PRODUCT(UpdateCollisions(collisions);) |
return probe; |
} |
@@ -210,8 +208,8 @@ NOT_IN_PRODUCT( |
deleted = probe; |
} |
} else { |
- key_handle_ = GetKey(probe); |
- if (KeyTraits::IsMatch(key, key_handle_)) { |
+ *key_handle_ = GetKey(probe); |
+ if (KeyTraits::IsMatch(key, *key_handle_)) { |
*entry = probe; |
NOT_IN_PRODUCT(UpdateCollisions(collisions);) |
return true; |
@@ -289,10 +287,10 @@ NOT_IN_PRODUCT( |
return GetSmiValueAt(kDeletedEntriesIndex); |
} |
Object& KeyHandle() const { |
- return key_handle_; |
+ return *key_handle_; |
} |
Smi& SmiHandle() const { |
- return smi_handle_; |
+ return *smi_handle_; |
} |
NOT_IN_PRODUCT( |
@@ -376,24 +374,21 @@ NOT_IN_PRODUCT( |
intptr_t GetSmiValueAt(intptr_t index) const { |
ASSERT(!data_->IsNull()); |
- ASSERT(Object::Handle(zone(), data_->At(index)).IsSmi()); |
+ ASSERT(!data_->At(index)->IsHeapObject()); |
return Smi::Value(Smi::RawCast(data_->At(index))); |
} |
void SetSmiValueAt(intptr_t index, intptr_t value) const { |
- smi_handle_ = Smi::New(value); |
- data_->SetAt(index, smi_handle_); |
+ *smi_handle_ = Smi::New(value); |
+ data_->SetAt(index, *smi_handle_); |
} |
void AdjustSmiValueAt(intptr_t index, intptr_t delta) const { |
SetSmiValueAt(index, (GetSmiValueAt(index) + delta)); |
} |
- Zone* zone() const { return zone_; } |
- |
- Zone* zone_; |
- Object& key_handle_; |
- Smi& smi_handle_; |
+ Object* key_handle_; |
+ Smi* smi_handle_; |
// Exactly one of these is non-NULL, depending on whether Release was called. |
Array* data_; |
Array* released_data_; |
@@ -408,9 +403,11 @@ class UnorderedHashTable : public HashTable<KeyTraits, kUserPayloadSize, 0> { |
public: |
typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable; |
static const intptr_t kPayloadSize = kUserPayloadSize; |
- explicit UnorderedHashTable(RawArray* data) : BaseTable(data) {} |
- UnorderedHashTable(Zone* zone, RawArray* data) |
- : BaseTable(zone, data) {} |
+ explicit UnorderedHashTable(RawArray* data) |
+ : BaseTable(Thread::Current()->zone(), data) {} |
+ UnorderedHashTable(Zone* zone, RawArray* data) : BaseTable(zone, data) {} |
+ UnorderedHashTable(Object* key, Smi* value, Array* data) |
+ : BaseTable(key, value, data) {} |
// Note: Does not check for concurrent modification. |
class Iterator { |
public: |
@@ -447,9 +444,12 @@ class EnumIndexHashTable |
typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable; |
static const intptr_t kPayloadSize = kUserPayloadSize; |
static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex; |
+ EnumIndexHashTable(Object* key, Smi* value, Array* data) |
+ : BaseTable(key, value, data) {} |
EnumIndexHashTable(Zone* zone, RawArray* data) |
: BaseTable(zone, data) {} |
- explicit EnumIndexHashTable(RawArray* data) : BaseTable(data) {} |
+ explicit EnumIndexHashTable(RawArray* data) |
+ : BaseTable(Thread::Current()->zone(), data) {} |
// Note: Does not check for concurrent modification. |
class Iterator { |
public: |
@@ -509,7 +509,7 @@ class HashTables : public AllStatic { |
template<typename Table> |
static RawArray* New(intptr_t initial_capacity, |
Heap::Space space = Heap::kNew) { |
- Table table(Array::New( |
+ Table table(Thread::Current()->zone(), Array::New( |
Table::ArrayLengthForNumOccupied(initial_capacity), space)); |
table.Initialize(); |
return table.Release().raw(); |
@@ -517,7 +517,7 @@ class HashTables : public AllStatic { |
template<typename Table> |
static RawArray* New(const Array& array) { |
- Table table(array.raw()); |
+ Table table(Thread::Current()->zone(), array.raw()); |
table.Initialize(); |
return table.Release().raw(); |
} |
@@ -590,8 +590,11 @@ class HashTables : public AllStatic { |
template<typename BaseIterTable> |
class HashMap : public BaseIterTable { |
public: |
- explicit HashMap(RawArray* data) : BaseIterTable(data) {} |
+ explicit HashMap(RawArray* data) |
+ : BaseIterTable(Thread::Current()->zone(), data) {} |
HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {} |
+ HashMap(Object* key, Smi* value, Array* data) |
+ : BaseIterTable(key, value, data) {} |
template<typename Key> |
RawObject* GetOrNull(const Key& key, bool* present = NULL) const { |
intptr_t entry = BaseIterTable::FindKey(key); |
@@ -676,8 +679,11 @@ template<typename KeyTraits> |
class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > { |
public: |
typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap; |
- explicit UnorderedHashMap(RawArray* data) : BaseMap(data) {} |
+ explicit UnorderedHashMap(RawArray* data) |
+ : BaseMap(Thread::Current()->zone(), data) {} |
UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {} |
+ UnorderedHashMap(Object* key, Smi* value, Array* data) |
+ : BaseMap(key, value, data) {} |
}; |
@@ -685,16 +691,22 @@ template<typename KeyTraits> |
class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > { |
public: |
typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap; |
- explicit EnumIndexHashMap(RawArray* data) : BaseMap(data) {} |
+ explicit EnumIndexHashMap(RawArray* data) |
+ : BaseMap(Thread::Current()->zone(), data) {} |
EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {} |
+ EnumIndexHashMap(Object* key, Smi* value, Array* data) |
+ : BaseMap(key, value, data) {} |
}; |
template<typename BaseIterTable> |
class HashSet : public BaseIterTable { |
public: |
- explicit HashSet(RawArray* data) : BaseIterTable(data) {} |
+ explicit HashSet(RawArray* data) |
+ : BaseIterTable(Thread::Current()->zone(), data) {} |
HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {} |
+ HashSet(Object* key, Smi* value, Array* data) |
+ : BaseIterTable(key, value, data) {} |
bool Insert(const Object& key) { |
EnsureCapacity(); |
intptr_t entry = -1; |
@@ -770,10 +782,13 @@ template<typename KeyTraits> |
class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > { |
public: |
typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet; |
- explicit UnorderedHashSet(RawArray* data) : BaseSet(data) { |
+ explicit UnorderedHashSet(RawArray* data) |
+ : BaseSet(Thread::Current()->zone(), data) { |
ASSERT(data != Array::null()); |
} |
UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} |
+ UnorderedHashSet(Object* key, Smi* value, Array* data) |
+ : BaseSet(key, value, data) {} |
}; |
@@ -781,8 +796,11 @@ template<typename KeyTraits> |
class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > { |
public: |
typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet; |
- explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {} |
+ explicit EnumIndexHashSet(RawArray* data) |
+ : BaseSet(Thread::Current()->zone(), data) {} |
EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} |
+ EnumIndexHashSet(Object* key, Smi* value, Array* data) |
+ : BaseSet(key, value, data) {} |
}; |
} // namespace dart |