Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: runtime/vm/hash_table.h

Issue 1934263003: - Add a new constructor to the hash table classes that allow handles to be passed in instead of cre… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address-code-review-comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/hash_table_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_HASH_TABLE_H_ 5 #ifndef VM_HASH_TABLE_H_
6 #define VM_HASH_TABLE_H_ 6 #define VM_HASH_TABLE_H_
7 7
8 // Temporarily used when sorting the indices in EnumIndexHashTable. 8 // Temporarily used when sorting the indices in EnumIndexHashTable.
9 // TODO(koda): Remove these dependencies before using in production. 9 // TODO(koda): Remove these dependencies before using in production.
10 #include <map> 10 #include <map>
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 // Parameters 78 // Parameters
79 // KeyTraits: defines static methods 79 // KeyTraits: defines static methods
80 // bool IsMatch(const Key& key, const Object& obj) and 80 // bool IsMatch(const Key& key, const Object& obj) and
81 // uword Hash(const Key& key) for any number of desired lookup key types. 81 // uword Hash(const Key& key) for any number of desired lookup key types.
82 // kPayloadSize: number of components of the payload in each entry. 82 // kPayloadSize: number of components of the payload in each entry.
83 // kMetaDataSize: number of elements reserved (e.g., for iteration order data). 83 // kMetaDataSize: number of elements reserved (e.g., for iteration order data).
84 template<typename KeyTraits, intptr_t kPayloadSize, intptr_t kMetaDataSize> 84 template<typename KeyTraits, intptr_t kPayloadSize, intptr_t kMetaDataSize>
85 class HashTable : public ValueObject { 85 class HashTable : public ValueObject {
86 public: 86 public:
87 typedef KeyTraits Traits; 87 typedef KeyTraits Traits;
88 // Uses the passed in handles for all handle operations.
89 // 'Release' must be called at the end to obtain the final table
90 // after potential growth/shrinkage.
91 HashTable(Object* key, Smi* index, Array* data)
92 : key_handle_(key),
93 smi_handle_(index),
94 data_(data),
95 released_data_(NULL) {}
88 // Uses 'zone' for handle allocation. 'Release' must be called at the end 96 // Uses 'zone' for handle allocation. 'Release' must be called at the end
89 // to obtain the final table after potential growth/shrinkage. 97 // to obtain the final table after potential growth/shrinkage.
90 HashTable(Zone* zone, RawArray* data) 98 HashTable(Zone* zone, RawArray* data)
91 : zone_(zone), 99 : key_handle_(&Object::Handle(zone)),
92 key_handle_(Object::Handle(zone_)), 100 smi_handle_(&Smi::Handle(zone)),
93 smi_handle_(Smi::Handle(zone_)), 101 data_(&Array::Handle(zone, data)),
94 data_(&Array::Handle(zone_, data)),
95 released_data_(NULL) {} 102 released_data_(NULL) {}
96 // Like above, except uses current zone.
97 explicit HashTable(RawArray* data)
98 : zone_(Thread::Current()->zone()),
99 key_handle_(Object::Handle(zone_)),
100 smi_handle_(Smi::Handle(zone_)),
101 data_(&Array::Handle(zone_, data)),
102 released_data_(NULL) {
103 ASSERT(!data_->IsNull());
104 }
105 103
106 // Returns the final table. The handle is cleared when this HashTable is 104 // Returns the final table. The handle is cleared when this HashTable is
107 // destroyed. 105 // destroyed.
108 Array& Release() { 106 Array& Release() {
109 ASSERT(data_ != NULL); 107 ASSERT(data_ != NULL);
110 ASSERT(released_data_ == NULL); 108 ASSERT(released_data_ == NULL);
111 // Ensure that no methods are called after 'Release'. 109 // Ensure that no methods are called after 'Release'.
112 released_data_ = data_; 110 released_data_ = data_;
113 data_ = NULL; 111 data_ = NULL;
114 return *released_data_; 112 return *released_data_;
(...skipping 12 matching lines...) Expand all
127 static intptr_t ArrayLengthForNumOccupied(intptr_t num_occupied) { 125 static intptr_t ArrayLengthForNumOccupied(intptr_t num_occupied) {
128 // The current invariant requires at least one unoccupied entry. 126 // The current invariant requires at least one unoccupied entry.
129 // TODO(koda): Adjust if moving to quadratic probing. 127 // TODO(koda): Adjust if moving to quadratic probing.
130 intptr_t num_entries = num_occupied + 1; 128 intptr_t num_entries = num_occupied + 1;
131 return kFirstKeyIndex + (kEntrySize * num_entries); 129 return kFirstKeyIndex + (kEntrySize * num_entries);
132 } 130 }
133 131
134 // Initializes an empty table. 132 // Initializes an empty table.
135 void Initialize() const { 133 void Initialize() const {
136 ASSERT(data_->Length() >= ArrayLengthForNumOccupied(0)); 134 ASSERT(data_->Length() >= ArrayLengthForNumOccupied(0));
137 smi_handle_ = Smi::New(0); 135 *smi_handle_ = Smi::New(0);
138 data_->SetAt(kOccupiedEntriesIndex, smi_handle_); 136 data_->SetAt(kOccupiedEntriesIndex, *smi_handle_);
139 data_->SetAt(kDeletedEntriesIndex, smi_handle_); 137 data_->SetAt(kDeletedEntriesIndex, *smi_handle_);
140 138
141 NOT_IN_PRODUCT( 139 NOT_IN_PRODUCT(
142 data_->SetAt(kNumGrowsIndex, smi_handle_); 140 data_->SetAt(kNumGrowsIndex, *smi_handle_);
143 data_->SetAt(kNumLT5LookupsIndex, smi_handle_); 141 data_->SetAt(kNumLT5LookupsIndex, *smi_handle_);
144 data_->SetAt(kNumLT25LookupsIndex, smi_handle_); 142 data_->SetAt(kNumLT25LookupsIndex, *smi_handle_);
145 data_->SetAt(kNumGT25LookupsIndex, smi_handle_); 143 data_->SetAt(kNumGT25LookupsIndex, *smi_handle_);
146 ) // !PRODUCT 144 ) // !PRODUCT
147 145
148 for (intptr_t i = kHeaderSize; i < data_->Length(); ++i) { 146 for (intptr_t i = kHeaderSize; i < data_->Length(); ++i) {
149 data_->SetAt(i, Object::sentinel()); 147 data_->SetAt(i, Object::sentinel());
150 } 148 }
151 } 149 }
152 150
153 // Returns whether 'key' matches any key in the table. 151 // Returns whether 'key' matches any key in the table.
154 template<typename Key> 152 template<typename Key>
155 bool ContainsKey(const Key& key) const { 153 bool ContainsKey(const Key& key) const {
156 return FindKey(key) != -1; 154 return FindKey(key) != -1;
157 } 155 }
158 156
159 // Returns the entry that matches 'key', or -1 if none exists. 157 // Returns the entry that matches 'key', or -1 if none exists.
160 template<typename Key> 158 template<typename Key>
161 intptr_t FindKey(const Key& key) const { 159 intptr_t FindKey(const Key& key) const {
162 const intptr_t num_entries = NumEntries(); 160 const intptr_t num_entries = NumEntries();
163 ASSERT(NumOccupied() < num_entries); 161 ASSERT(NumOccupied() < num_entries);
164 // TODO(koda): Add salt. 162 // TODO(koda): Add salt.
165 NOT_IN_PRODUCT(intptr_t collisions = 0;) 163 NOT_IN_PRODUCT(intptr_t collisions = 0;)
166 uword hash = KeyTraits::Hash(key); 164 uword hash = KeyTraits::Hash(key);
167 intptr_t probe = hash % num_entries; 165 intptr_t probe = hash % num_entries;
168 // TODO(koda): Consider quadratic probing. 166 // TODO(koda): Consider quadratic probing.
169 while (true) { 167 while (true) {
170 if (IsUnused(probe)) { 168 if (IsUnused(probe)) {
171 NOT_IN_PRODUCT(UpdateCollisions(collisions);) 169 NOT_IN_PRODUCT(UpdateCollisions(collisions);)
172 return -1; 170 return -1;
173 } else if (!IsDeleted(probe)) { 171 } else if (!IsDeleted(probe)) {
174 key_handle_ = GetKey(probe); 172 *key_handle_ = GetKey(probe);
175 if (KeyTraits::IsMatch(key, key_handle_)) { 173 if (KeyTraits::IsMatch(key, *key_handle_)) {
176 NOT_IN_PRODUCT(UpdateCollisions(collisions);) 174 NOT_IN_PRODUCT(UpdateCollisions(collisions);)
177 return probe; 175 return probe;
178 } 176 }
179 NOT_IN_PRODUCT(collisions += 1;) 177 NOT_IN_PRODUCT(collisions += 1;)
180 } 178 }
181 // Advance probe. 179 // Advance probe.
182 probe++; 180 probe++;
183 probe = (probe == num_entries) ? 0 : probe; 181 probe = (probe == num_entries) ? 0 : probe;
184 } 182 }
185 UNREACHABLE(); 183 UNREACHABLE();
(...skipping 17 matching lines...) Expand all
203 while (true) { 201 while (true) {
204 if (IsUnused(probe)) { 202 if (IsUnused(probe)) {
205 *entry = (deleted != -1) ? deleted : probe; 203 *entry = (deleted != -1) ? deleted : probe;
206 NOT_IN_PRODUCT(UpdateCollisions(collisions);) 204 NOT_IN_PRODUCT(UpdateCollisions(collisions);)
207 return false; 205 return false;
208 } else if (IsDeleted(probe)) { 206 } else if (IsDeleted(probe)) {
209 if (deleted == -1) { 207 if (deleted == -1) {
210 deleted = probe; 208 deleted = probe;
211 } 209 }
212 } else { 210 } else {
213 key_handle_ = GetKey(probe); 211 *key_handle_ = GetKey(probe);
214 if (KeyTraits::IsMatch(key, key_handle_)) { 212 if (KeyTraits::IsMatch(key, *key_handle_)) {
215 *entry = probe; 213 *entry = probe;
216 NOT_IN_PRODUCT(UpdateCollisions(collisions);) 214 NOT_IN_PRODUCT(UpdateCollisions(collisions);)
217 return true; 215 return true;
218 } 216 }
219 NOT_IN_PRODUCT(collisions += 1;) 217 NOT_IN_PRODUCT(collisions += 1;)
220 } 218 }
221 // Advance probe. 219 // Advance probe.
222 probe++; 220 probe++;
223 probe = (probe == num_entries) ? 0 : probe; 221 probe = (probe == num_entries) ? 0 : probe;
224 } 222 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 intptr_t NumUnused() const { 280 intptr_t NumUnused() const {
283 return NumEntries() - NumOccupied() - NumDeleted(); 281 return NumEntries() - NumOccupied() - NumDeleted();
284 } 282 }
285 intptr_t NumOccupied() const { 283 intptr_t NumOccupied() const {
286 return GetSmiValueAt(kOccupiedEntriesIndex); 284 return GetSmiValueAt(kOccupiedEntriesIndex);
287 } 285 }
288 intptr_t NumDeleted() const { 286 intptr_t NumDeleted() const {
289 return GetSmiValueAt(kDeletedEntriesIndex); 287 return GetSmiValueAt(kDeletedEntriesIndex);
290 } 288 }
291 Object& KeyHandle() const { 289 Object& KeyHandle() const {
292 return key_handle_; 290 return *key_handle_;
293 } 291 }
294 Smi& SmiHandle() const { 292 Smi& SmiHandle() const {
295 return smi_handle_; 293 return *smi_handle_;
296 } 294 }
297 295
298 NOT_IN_PRODUCT( 296 NOT_IN_PRODUCT(
299 intptr_t NumGrows() const { 297 intptr_t NumGrows() const {
300 return GetSmiValueAt(kNumGrowsIndex); 298 return GetSmiValueAt(kNumGrowsIndex);
301 } 299 }
302 intptr_t NumLT5Collisions() const { 300 intptr_t NumLT5Collisions() const {
303 return GetSmiValueAt(kNumLT5LookupsIndex); 301 return GetSmiValueAt(kNumLT5LookupsIndex);
304 } 302 }
305 intptr_t NumLT25Collisions() const { 303 intptr_t NumLT25Collisions() const {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 RawObject* InternalGetKey(intptr_t entry) const { 367 RawObject* InternalGetKey(intptr_t entry) const {
370 return data_->At(KeyIndex(entry)); 368 return data_->At(KeyIndex(entry));
371 } 369 }
372 370
373 void InternalSetKey(intptr_t entry, const Object& key) const { 371 void InternalSetKey(intptr_t entry, const Object& key) const {
374 data_->SetAt(KeyIndex(entry), key); 372 data_->SetAt(KeyIndex(entry), key);
375 } 373 }
376 374
377 intptr_t GetSmiValueAt(intptr_t index) const { 375 intptr_t GetSmiValueAt(intptr_t index) const {
378 ASSERT(!data_->IsNull()); 376 ASSERT(!data_->IsNull());
379 ASSERT(Object::Handle(zone(), data_->At(index)).IsSmi()); 377 ASSERT(!data_->At(index)->IsHeapObject());
380 return Smi::Value(Smi::RawCast(data_->At(index))); 378 return Smi::Value(Smi::RawCast(data_->At(index)));
381 } 379 }
382 380
383 void SetSmiValueAt(intptr_t index, intptr_t value) const { 381 void SetSmiValueAt(intptr_t index, intptr_t value) const {
384 smi_handle_ = Smi::New(value); 382 *smi_handle_ = Smi::New(value);
385 data_->SetAt(index, smi_handle_); 383 data_->SetAt(index, *smi_handle_);
386 } 384 }
387 385
388 void AdjustSmiValueAt(intptr_t index, intptr_t delta) const { 386 void AdjustSmiValueAt(intptr_t index, intptr_t delta) const {
389 SetSmiValueAt(index, (GetSmiValueAt(index) + delta)); 387 SetSmiValueAt(index, (GetSmiValueAt(index) + delta));
390 } 388 }
391 389
392 Zone* zone() const { return zone_; } 390 Object* key_handle_;
393 391 Smi* smi_handle_;
394 Zone* zone_;
395 Object& key_handle_;
396 Smi& smi_handle_;
397 // Exactly one of these is non-NULL, depending on whether Release was called. 392 // Exactly one of these is non-NULL, depending on whether Release was called.
398 Array* data_; 393 Array* data_;
399 Array* released_data_; 394 Array* released_data_;
400 395
401 friend class HashTables; 396 friend class HashTables;
402 }; 397 };
403 398
404 399
405 // Table with unspecified iteration order. No payload overhead or metadata. 400 // Table with unspecified iteration order. No payload overhead or metadata.
406 template<typename KeyTraits, intptr_t kUserPayloadSize> 401 template<typename KeyTraits, intptr_t kUserPayloadSize>
407 class UnorderedHashTable : public HashTable<KeyTraits, kUserPayloadSize, 0> { 402 class UnorderedHashTable : public HashTable<KeyTraits, kUserPayloadSize, 0> {
408 public: 403 public:
409 typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable; 404 typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable;
410 static const intptr_t kPayloadSize = kUserPayloadSize; 405 static const intptr_t kPayloadSize = kUserPayloadSize;
411 explicit UnorderedHashTable(RawArray* data) : BaseTable(data) {} 406 explicit UnorderedHashTable(RawArray* data)
412 UnorderedHashTable(Zone* zone, RawArray* data) 407 : BaseTable(Thread::Current()->zone(), data) {}
413 : BaseTable(zone, data) {} 408 UnorderedHashTable(Zone* zone, RawArray* data) : BaseTable(zone, data) {}
409 UnorderedHashTable(Object* key, Smi* value, Array* data)
410 : BaseTable(key, value, data) {}
414 // Note: Does not check for concurrent modification. 411 // Note: Does not check for concurrent modification.
415 class Iterator { 412 class Iterator {
416 public: 413 public:
417 explicit Iterator(const UnorderedHashTable* table) 414 explicit Iterator(const UnorderedHashTable* table)
418 : table_(table), entry_(-1) {} 415 : table_(table), entry_(-1) {}
419 bool MoveNext() { 416 bool MoveNext() {
420 while (entry_ < (table_->NumEntries() - 1)) { 417 while (entry_ < (table_->NumEntries() - 1)) {
421 ++entry_; 418 ++entry_;
422 if (table_->IsOccupied(entry_)) { 419 if (table_->IsOccupied(entry_)) {
423 return true; 420 return true;
(...skipping 16 matching lines...) Expand all
440 437
441 // Table with insertion order, using one payload component for the enumeration 438 // Table with insertion order, using one payload component for the enumeration
442 // index, and one metadata element for the next enumeration index. 439 // index, and one metadata element for the next enumeration index.
443 template<typename KeyTraits, intptr_t kUserPayloadSize> 440 template<typename KeyTraits, intptr_t kUserPayloadSize>
444 class EnumIndexHashTable 441 class EnumIndexHashTable
445 : public HashTable<KeyTraits, kUserPayloadSize + 1, 1> { 442 : public HashTable<KeyTraits, kUserPayloadSize + 1, 1> {
446 public: 443 public:
447 typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable; 444 typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable;
448 static const intptr_t kPayloadSize = kUserPayloadSize; 445 static const intptr_t kPayloadSize = kUserPayloadSize;
449 static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex; 446 static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex;
447 EnumIndexHashTable(Object* key, Smi* value, Array* data)
448 : BaseTable(key, value, data) {}
450 EnumIndexHashTable(Zone* zone, RawArray* data) 449 EnumIndexHashTable(Zone* zone, RawArray* data)
451 : BaseTable(zone, data) {} 450 : BaseTable(zone, data) {}
452 explicit EnumIndexHashTable(RawArray* data) : BaseTable(data) {} 451 explicit EnumIndexHashTable(RawArray* data)
452 : BaseTable(Thread::Current()->zone(), data) {}
453 // Note: Does not check for concurrent modification. 453 // Note: Does not check for concurrent modification.
454 class Iterator { 454 class Iterator {
455 public: 455 public:
456 explicit Iterator(const EnumIndexHashTable* table) : index_(-1) { 456 explicit Iterator(const EnumIndexHashTable* table) : index_(-1) {
457 // TODO(koda): Use GrowableArray after adding stateful comparator support. 457 // TODO(koda): Use GrowableArray after adding stateful comparator support.
458 std::map<intptr_t, intptr_t> enum_to_entry; 458 std::map<intptr_t, intptr_t> enum_to_entry;
459 for (intptr_t i = 0; i < table->NumEntries(); ++i) { 459 for (intptr_t i = 0; i < table->NumEntries(); ++i) {
460 if (table->IsOccupied(i)) { 460 if (table->IsOccupied(i)) {
461 intptr_t enum_index = 461 intptr_t enum_index =
462 table->GetSmiValueAt(table->PayloadIndex(i, kPayloadSize)); 462 table->GetSmiValueAt(table->PayloadIndex(i, kPayloadSize));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 // No extra book-keeping needed for DeleteEntry. 502 // No extra book-keeping needed for DeleteEntry.
503 }; 503 };
504 504
505 505
506 class HashTables : public AllStatic { 506 class HashTables : public AllStatic {
507 public: 507 public:
508 // Allocates and initializes a table. 508 // Allocates and initializes a table.
509 template<typename Table> 509 template<typename Table>
510 static RawArray* New(intptr_t initial_capacity, 510 static RawArray* New(intptr_t initial_capacity,
511 Heap::Space space = Heap::kNew) { 511 Heap::Space space = Heap::kNew) {
512 Table table(Array::New( 512 Table table(Thread::Current()->zone(), Array::New(
513 Table::ArrayLengthForNumOccupied(initial_capacity), space)); 513 Table::ArrayLengthForNumOccupied(initial_capacity), space));
514 table.Initialize(); 514 table.Initialize();
515 return table.Release().raw(); 515 return table.Release().raw();
516 } 516 }
517 517
518 template<typename Table> 518 template<typename Table>
519 static RawArray* New(const Array& array) { 519 static RawArray* New(const Array& array) {
520 Table table(array.raw()); 520 Table table(Thread::Current()->zone(), array.raw());
521 table.Initialize(); 521 table.Initialize();
522 return table.Release().raw(); 522 return table.Release().raw();
523 } 523 }
524 524
525 // Clears 'to' and inserts all elements from 'from', in iteration order. 525 // Clears 'to' and inserts all elements from 'from', in iteration order.
526 // The tables must have the same user payload size. 526 // The tables must have the same user payload size.
527 template<typename From, typename To> 527 template<typename From, typename To>
528 static void Copy(const From& from, const To& to) { 528 static void Copy(const From& from, const To& to) {
529 COMPILE_ASSERT(From::kPayloadSize == To::kPayloadSize); 529 COMPILE_ASSERT(From::kPayloadSize == To::kPayloadSize);
530 to.Initialize(); 530 to.Initialize();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 } 583 }
584 } 584 }
585 return result.raw(); 585 return result.raw();
586 } 586 }
587 }; 587 };
588 588
589 589
590 template<typename BaseIterTable> 590 template<typename BaseIterTable>
591 class HashMap : public BaseIterTable { 591 class HashMap : public BaseIterTable {
592 public: 592 public:
593 explicit HashMap(RawArray* data) : BaseIterTable(data) {} 593 explicit HashMap(RawArray* data)
594 : BaseIterTable(Thread::Current()->zone(), data) {}
594 HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {} 595 HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
596 HashMap(Object* key, Smi* value, Array* data)
597 : BaseIterTable(key, value, data) {}
595 template<typename Key> 598 template<typename Key>
596 RawObject* GetOrNull(const Key& key, bool* present = NULL) const { 599 RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
597 intptr_t entry = BaseIterTable::FindKey(key); 600 intptr_t entry = BaseIterTable::FindKey(key);
598 if (present != NULL) { 601 if (present != NULL) {
599 *present = (entry != -1); 602 *present = (entry != -1);
600 } 603 }
601 return (entry == -1) ? Object::null() : BaseIterTable::GetPayload(entry, 0); 604 return (entry == -1) ? Object::null() : BaseIterTable::GetPayload(entry, 0);
602 } 605 }
603 bool UpdateOrInsert(const Object& key, const Object& value) const { 606 bool UpdateOrInsert(const Object& key, const Object& value) const {
604 EnsureCapacity(); 607 EnsureCapacity();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 // We currently never shrink. 672 // We currently never shrink.
670 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this); 673 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this);
671 } 674 }
672 }; 675 };
673 676
674 677
675 template<typename KeyTraits> 678 template<typename KeyTraits>
676 class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > { 679 class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > {
677 public: 680 public:
678 typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap; 681 typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap;
679 explicit UnorderedHashMap(RawArray* data) : BaseMap(data) {} 682 explicit UnorderedHashMap(RawArray* data)
683 : BaseMap(Thread::Current()->zone(), data) {}
680 UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {} 684 UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
685 UnorderedHashMap(Object* key, Smi* value, Array* data)
686 : BaseMap(key, value, data) {}
681 }; 687 };
682 688
683 689
684 template<typename KeyTraits> 690 template<typename KeyTraits>
685 class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > { 691 class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > {
686 public: 692 public:
687 typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap; 693 typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap;
688 explicit EnumIndexHashMap(RawArray* data) : BaseMap(data) {} 694 explicit EnumIndexHashMap(RawArray* data)
695 : BaseMap(Thread::Current()->zone(), data) {}
689 EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {} 696 EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
697 EnumIndexHashMap(Object* key, Smi* value, Array* data)
698 : BaseMap(key, value, data) {}
690 }; 699 };
691 700
692 701
693 template<typename BaseIterTable> 702 template<typename BaseIterTable>
694 class HashSet : public BaseIterTable { 703 class HashSet : public BaseIterTable {
695 public: 704 public:
696 explicit HashSet(RawArray* data) : BaseIterTable(data) {} 705 explicit HashSet(RawArray* data)
706 : BaseIterTable(Thread::Current()->zone(), data) {}
697 HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {} 707 HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
708 HashSet(Object* key, Smi* value, Array* data)
709 : BaseIterTable(key, value, data) {}
698 bool Insert(const Object& key) { 710 bool Insert(const Object& key) {
699 EnsureCapacity(); 711 EnsureCapacity();
700 intptr_t entry = -1; 712 intptr_t entry = -1;
701 bool present = BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry); 713 bool present = BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry);
702 if (!present) { 714 if (!present) {
703 BaseIterTable::InsertKey(entry, key); 715 BaseIterTable::InsertKey(entry, key);
704 } 716 }
705 return present; 717 return present;
706 } 718 }
707 719
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 // We currently never shrink. 775 // We currently never shrink.
764 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this); 776 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this);
765 } 777 }
766 }; 778 };
767 779
768 780
769 template<typename KeyTraits> 781 template<typename KeyTraits>
770 class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > { 782 class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
771 public: 783 public:
772 typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet; 784 typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
773 explicit UnorderedHashSet(RawArray* data) : BaseSet(data) { 785 explicit UnorderedHashSet(RawArray* data)
786 : BaseSet(Thread::Current()->zone(), data) {
774 ASSERT(data != Array::null()); 787 ASSERT(data != Array::null());
775 } 788 }
776 UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} 789 UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
790 UnorderedHashSet(Object* key, Smi* value, Array* data)
791 : BaseSet(key, value, data) {}
777 }; 792 };
778 793
779 794
780 template<typename KeyTraits> 795 template<typename KeyTraits>
781 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > { 796 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > {
782 public: 797 public:
783 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet; 798 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet;
784 explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {} 799 explicit EnumIndexHashSet(RawArray* data)
800 : BaseSet(Thread::Current()->zone(), data) {}
785 EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} 801 EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
802 EnumIndexHashSet(Object* key, Smi* value, Array* data)
803 : BaseSet(key, value, data) {}
786 }; 804 };
787 805
788 } // namespace dart 806 } // namespace dart
789 807
790 #endif // VM_HASH_TABLE_H_ 808 #endif // VM_HASH_TABLE_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/hash_table_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698