Chromium Code Reviews| Index: runtime/vm/hash_table.h |
| =================================================================== |
| --- runtime/vm/hash_table.h (revision 39467) |
| +++ runtime/vm/hash_table.h (working copy) |
| @@ -87,10 +87,16 @@ |
| // Uses 'isolate' for handle allocation. 'Release' must be called at the end |
| // to obtain the final table after potential growth/shrinkage. |
| HashTable(Isolate* isolate, RawArray* data) |
| - : isolate_(isolate), data_(&Array::Handle(isolate_, data)) {} |
| + : isolate_(isolate), |
| + key_handle_(Object::Handle(isolate_)), |
| + smi_handle_(Smi::Handle(isolate_)), |
| + data_(&Array::Handle(isolate_, data)) {} |
| // Like above, except uses current isolate. |
| explicit HashTable(RawArray* data) |
| - : isolate_(Isolate::Current()), data_(&Array::Handle(isolate_, data)) {} |
| + : isolate_(Isolate::Current()), |
| + key_handle_(Object::Handle(isolate_)), |
| + smi_handle_(Smi::Handle(isolate_)), |
| + data_(&Array::Handle(isolate_, data)) {} |
| Array& Release() { |
| ASSERT(data_ != NULL); |
| @@ -117,9 +123,9 @@ |
| // Initializes an empty table. |
| void Initialize() const { |
| ASSERT(data_->Length() >= ArrayLengthForNumOccupied(0)); |
| - Smi& zero = Smi::Handle(isolate(), Smi::New(0)); |
| - data_->SetAt(kOccupiedEntriesIndex, zero); |
| - data_->SetAt(kDeletedEntriesIndex, zero); |
| + smi_handle_ = Smi::New(0); |
| + data_->SetAt(kOccupiedEntriesIndex, smi_handle_); |
| + data_->SetAt(kDeletedEntriesIndex, smi_handle_); |
| for (intptr_t i = kHeaderSize; i < data_->Length(); ++i) { |
| data_->SetAt(i, Object::sentinel()); |
| } |
| @@ -137,7 +143,6 @@ |
| ASSERT(NumOccupied() < NumEntries()); |
| // TODO(koda): Add salt. |
| intptr_t probe = static_cast<uword>(KeyTraits::Hash(key)) % NumEntries(); |
| - Object& obj = Object::Handle(isolate()); |
| // TODO(koda): Consider quadratic probing. |
| for (; ; probe = (probe + 1) % NumEntries()) { |
| if (IsUnused(probe)) { |
| @@ -145,8 +150,8 @@ |
| } else if (IsDeleted(probe)) { |
| continue; |
| } else { |
| - obj = GetKey(probe); |
| - if (KeyTraits::IsMatch(key, obj)) { |
| + key_handle_ = GetKey(probe); |
| + if (KeyTraits::IsMatch(key, key_handle_)) { |
| return probe; |
| } |
| } |
| @@ -164,7 +169,6 @@ |
| ASSERT(entry != NULL); |
| ASSERT(NumOccupied() < NumEntries()); |
| intptr_t probe = static_cast<uword>(KeyTraits::Hash(key)) % NumEntries(); |
| - Object& obj = Object::Handle(isolate()); |
| intptr_t deleted = -1; |
| // TODO(koda): Consider quadratic probing. |
| for (; ; probe = (probe + 1) % NumEntries()) { |
| @@ -176,8 +180,8 @@ |
| deleted = probe; |
| } |
| } else { |
| - obj = GetKey(probe); |
| - if (KeyTraits::IsMatch(key, obj)) { |
| + key_handle_ = GetKey(probe); |
| + if (KeyTraits::IsMatch(key, key_handle_)) { |
| *entry = probe; |
| return true; |
| } |
| @@ -249,6 +253,12 @@ |
| intptr_t NumDeleted() const { |
| return GetSmiValueAt(kDeletedEntriesIndex); |
| } |
| + Object* KeyHandle() const { |
|
koda
2014/08/21 20:57:25
Does this need to return a pointer? You always see
siva
2014/08/21 23:54:30
Changed it to return the reference not a pointer.
|
| + return &key_handle_; |
| + } |
| + Smi* SmiHandle() const { |
| + return &smi_handle_; |
| + } |
| protected: |
| static const intptr_t kOccupiedEntriesIndex = 0; |
| @@ -282,8 +292,8 @@ |
| } |
| void SetSmiValueAt(intptr_t index, intptr_t value) const { |
| - const Smi& smi = Smi::Handle(isolate(), Smi::New(value)); |
| - data_->SetAt(index, smi); |
| + smi_handle_ = Smi::New(value); |
| + data_->SetAt(index, smi_handle_); |
| } |
| void AdjustSmiValueAt(intptr_t index, intptr_t delta) const { |
| @@ -293,6 +303,8 @@ |
| Isolate* isolate() const { return isolate_; } |
| Isolate* isolate_; |
| + Object& key_handle_; |
| + Smi& smi_handle_; |
| // This is a pointer rather than a reference, to enable Release nulling it, |
| // preventing post-Release modification. |
| Array* data_; |
| @@ -391,9 +403,11 @@ |
| void InsertKey(intptr_t entry, const Object& key) const { |
| BaseTable::InsertKey(entry, key); |
| - const Smi& next_enum_index = Smi::Handle(BaseTable::isolate(), |
| - Smi::New(BaseTable::GetSmiValueAt(kNextEnumIndex))); |
| - BaseTable::UpdatePayload(entry, kPayloadSize, next_enum_index); |
| + *(BaseTable::SmiHandle()) = |
| + Smi::New(BaseTable::GetSmiValueAt(kNextEnumIndex)); |
| + BaseTable::UpdatePayload(entry, |
| + kPayloadSize, |
| + *(BaseTable::SmiHandle())); |
| // TODO(koda): Handle possible Smi overflow from repeated insert/delete. |
| BaseTable::AdjustSmiValueAt(kNextEnumIndex, 1); |
| } |
| @@ -529,9 +543,9 @@ |
| EnsureCapacity(); |
| intptr_t entry = -1; |
| if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) { |
| - Object& new_key = Object::Handle(BaseIterTable::isolate(), |
| - BaseIterTable::BaseTable::Traits::NewKey(key)); |
| - BaseIterTable::InsertKey(entry, new_key); |
| + *(BaseIterTable::KeyHandle()) = |
| + BaseIterTable::BaseTable::Traits::NewKey(key); |
| + BaseIterTable::InsertKey(entry, *(BaseIterTable::KeyHandle())); |
| BaseIterTable::UpdatePayload(entry, 0, value_if_absent); |
| return value_if_absent.raw(); |
| } else { |
| @@ -610,10 +624,10 @@ |
| EnsureCapacity(); |
| intptr_t entry = -1; |
| if (!BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry)) { |
| - Object& new_key = Object::Handle(BaseIterTable::isolate(), |
| - BaseIterTable::BaseTable::Traits::NewKey(key)); |
| - BaseIterTable::InsertKey(entry, new_key); |
| - return new_key.raw(); |
| + *(BaseIterTable::KeyHandle()) = |
| + BaseIterTable::BaseTable::Traits::NewKey(key); |
| + BaseIterTable::InsertKey(entry, *(BaseIterTable::KeyHandle())); |
| + return BaseIterTable::KeyHandle()->raw(); |
| } else { |
| return BaseIterTable::GetKey(entry); |
| } |