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

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

Issue 1292433004: Migrate to Zone-based handle allocation in hash table and symbol table. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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/symbols.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 'isolate' for handle allocation. 'Release' must be called at the end 88 // Uses 'zone' for handle allocation. 'Release' must be called at the end
89 // to obtain the final table after potential growth/shrinkage. 89 // to obtain the final table after potential growth/shrinkage.
90 HashTable(Isolate* isolate, RawArray* data) 90 HashTable(Zone* zone, RawArray* data)
91 : isolate_(isolate), 91 : zone_(zone),
92 key_handle_(Object::Handle(isolate_)), 92 key_handle_(Object::Handle(zone_)),
93 smi_handle_(Smi::Handle(isolate_)), 93 smi_handle_(Smi::Handle(zone_)),
94 data_(&Array::Handle(isolate_, data)), 94 data_(&Array::Handle(zone_, data)),
95 released_data_(NULL) {} 95 released_data_(NULL) {}
96 // Like above, except uses current isolate. 96 // Like above, except uses current zone.
97 explicit HashTable(RawArray* data) 97 explicit HashTable(RawArray* data)
98 : isolate_(Isolate::Current()), 98 : zone_(Thread::Current()->zone()),
99 key_handle_(Object::Handle(isolate_)), 99 key_handle_(Object::Handle(zone_)),
100 smi_handle_(Smi::Handle(isolate_)), 100 smi_handle_(Smi::Handle(zone_)),
101 data_(&Array::Handle(isolate_, data)), 101 data_(&Array::Handle(zone_, data)),
102 released_data_(NULL) {} 102 released_data_(NULL) {}
103 103
104 // 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
105 // destroyed. 105 // destroyed.
106 Array& Release() { 106 Array& Release() {
107 ASSERT(data_ != NULL); 107 ASSERT(data_ != NULL);
108 ASSERT(released_data_ == NULL); 108 ASSERT(released_data_ == NULL);
109 // Ensure that no methods are called after 'Release'. 109 // Ensure that no methods are called after 'Release'.
110 released_data_ = data_; 110 released_data_ = data_;
111 data_ = NULL; 111 data_ = NULL;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 289
290 RawObject* InternalGetKey(intptr_t entry) const { 290 RawObject* InternalGetKey(intptr_t entry) const {
291 return data_->At(KeyIndex(entry)); 291 return data_->At(KeyIndex(entry));
292 } 292 }
293 293
294 void InternalSetKey(intptr_t entry, const Object& key) const { 294 void InternalSetKey(intptr_t entry, const Object& key) const {
295 data_->SetAt(KeyIndex(entry), key); 295 data_->SetAt(KeyIndex(entry), key);
296 } 296 }
297 297
298 intptr_t GetSmiValueAt(intptr_t index) const { 298 intptr_t GetSmiValueAt(intptr_t index) const {
299 ASSERT(Object::Handle(isolate(), data_->At(index)).IsSmi()); 299 ASSERT(Object::Handle(zone(), data_->At(index)).IsSmi());
300 return Smi::Value(Smi::RawCast(data_->At(index))); 300 return Smi::Value(Smi::RawCast(data_->At(index)));
301 } 301 }
302 302
303 void SetSmiValueAt(intptr_t index, intptr_t value) const { 303 void SetSmiValueAt(intptr_t index, intptr_t value) const {
304 smi_handle_ = Smi::New(value); 304 smi_handle_ = Smi::New(value);
305 data_->SetAt(index, smi_handle_); 305 data_->SetAt(index, smi_handle_);
306 } 306 }
307 307
308 void AdjustSmiValueAt(intptr_t index, intptr_t delta) const { 308 void AdjustSmiValueAt(intptr_t index, intptr_t delta) const {
309 SetSmiValueAt(index, (GetSmiValueAt(index) + delta)); 309 SetSmiValueAt(index, (GetSmiValueAt(index) + delta));
310 } 310 }
311 311
312 Isolate* isolate() const { return isolate_; } 312 Zone* zone() const { return zone_; }
313 313
314 Isolate* isolate_; 314 Zone* zone_;
315 Object& key_handle_; 315 Object& key_handle_;
316 Smi& smi_handle_; 316 Smi& smi_handle_;
317 // Exactly one of these is non-NULL, depending on whether Release was called. 317 // Exactly one of these is non-NULL, depending on whether Release was called.
318 Array* data_; 318 Array* data_;
319 Array* released_data_; 319 Array* released_data_;
320 320
321 friend class HashTables; 321 friend class HashTables;
322 }; 322 };
323 323
324 324
325 // Table with unspecified iteration order. No payload overhead or metadata. 325 // Table with unspecified iteration order. No payload overhead or metadata.
326 template<typename KeyTraits, intptr_t kUserPayloadSize> 326 template<typename KeyTraits, intptr_t kUserPayloadSize>
327 class UnorderedHashTable : public HashTable<KeyTraits, kUserPayloadSize, 0> { 327 class UnorderedHashTable : public HashTable<KeyTraits, kUserPayloadSize, 0> {
328 public: 328 public:
329 typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable; 329 typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable;
330 static const intptr_t kPayloadSize = kUserPayloadSize; 330 static const intptr_t kPayloadSize = kUserPayloadSize;
331 explicit UnorderedHashTable(RawArray* data) : BaseTable(data) {} 331 explicit UnorderedHashTable(RawArray* data) : BaseTable(data) {}
332 UnorderedHashTable(Isolate* isolate, RawArray* data) 332 UnorderedHashTable(Zone* zone, RawArray* data)
333 : BaseTable(isolate, data) {} 333 : BaseTable(zone, data) {}
334 // Note: Does not check for concurrent modification. 334 // Note: Does not check for concurrent modification.
335 class Iterator { 335 class Iterator {
336 public: 336 public:
337 explicit Iterator(const UnorderedHashTable* table) 337 explicit Iterator(const UnorderedHashTable* table)
338 : table_(table), entry_(-1) {} 338 : table_(table), entry_(-1) {}
339 bool MoveNext() { 339 bool MoveNext() {
340 while (entry_ < (table_->NumEntries() - 1)) { 340 while (entry_ < (table_->NumEntries() - 1)) {
341 ++entry_; 341 ++entry_;
342 if (table_->IsOccupied(entry_)) { 342 if (table_->IsOccupied(entry_)) {
343 return true; 343 return true;
(...skipping 16 matching lines...) Expand all
360 360
361 // Table with insertion order, using one payload component for the enumeration 361 // Table with insertion order, using one payload component for the enumeration
362 // index, and one metadata element for the next enumeration index. 362 // index, and one metadata element for the next enumeration index.
363 template<typename KeyTraits, intptr_t kUserPayloadSize> 363 template<typename KeyTraits, intptr_t kUserPayloadSize>
364 class EnumIndexHashTable 364 class EnumIndexHashTable
365 : public HashTable<KeyTraits, kUserPayloadSize + 1, 1> { 365 : public HashTable<KeyTraits, kUserPayloadSize + 1, 1> {
366 public: 366 public:
367 typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable; 367 typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable;
368 static const intptr_t kPayloadSize = kUserPayloadSize; 368 static const intptr_t kPayloadSize = kUserPayloadSize;
369 static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex; 369 static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex;
370 EnumIndexHashTable(Isolate* isolate, RawArray* data) 370 EnumIndexHashTable(Zone* zone, RawArray* data)
371 : BaseTable(isolate, data) {} 371 : BaseTable(zone, data) {}
372 explicit EnumIndexHashTable(RawArray* data) : BaseTable(data) {} 372 explicit EnumIndexHashTable(RawArray* data) : BaseTable(data) {}
373 // Note: Does not check for concurrent modification. 373 // Note: Does not check for concurrent modification.
374 class Iterator { 374 class Iterator {
375 public: 375 public:
376 explicit Iterator(const EnumIndexHashTable* table) : index_(-1) { 376 explicit Iterator(const EnumIndexHashTable* table) : index_(-1) {
377 // TODO(koda): Use GrowableArray after adding stateful comparator support. 377 // TODO(koda): Use GrowableArray after adding stateful comparator support.
378 std::map<intptr_t, intptr_t> enum_to_entry; 378 std::map<intptr_t, intptr_t> enum_to_entry;
379 for (intptr_t i = 0; i < table->NumEntries(); ++i) { 379 for (intptr_t i = 0; i < table->NumEntries(); ++i) {
380 if (table->IsOccupied(i)) { 380 if (table->IsOccupied(i)) {
381 intptr_t enum_index = 381 intptr_t enum_index =
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 } 496 }
497 return result.raw(); 497 return result.raw();
498 } 498 }
499 }; 499 };
500 500
501 501
502 template<typename BaseIterTable> 502 template<typename BaseIterTable>
503 class HashMap : public BaseIterTable { 503 class HashMap : public BaseIterTable {
504 public: 504 public:
505 explicit HashMap(RawArray* data) : BaseIterTable(data) {} 505 explicit HashMap(RawArray* data) : BaseIterTable(data) {}
506 HashMap(Isolate* isolate, RawArray* data) : BaseIterTable(isolate, data) {} 506 HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
507 template<typename Key> 507 template<typename Key>
508 RawObject* GetOrNull(const Key& key, bool* present = NULL) const { 508 RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
509 intptr_t entry = BaseIterTable::FindKey(key); 509 intptr_t entry = BaseIterTable::FindKey(key);
510 if (present != NULL) { 510 if (present != NULL) {
511 *present = (entry != -1); 511 *present = (entry != -1);
512 } 512 }
513 return (entry == -1) ? Object::null() : BaseIterTable::GetPayload(entry, 0); 513 return (entry == -1) ? Object::null() : BaseIterTable::GetPayload(entry, 0);
514 } 514 }
515 bool UpdateOrInsert(const Object& key, const Object& value) const { 515 bool UpdateOrInsert(const Object& key, const Object& value) const {
516 EnsureCapacity(); 516 EnsureCapacity();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this); 582 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this);
583 } 583 }
584 }; 584 };
585 585
586 586
587 template<typename KeyTraits> 587 template<typename KeyTraits>
588 class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > { 588 class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > {
589 public: 589 public:
590 typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap; 590 typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap;
591 explicit UnorderedHashMap(RawArray* data) : BaseMap(data) {} 591 explicit UnorderedHashMap(RawArray* data) : BaseMap(data) {}
592 UnorderedHashMap(Isolate* isolate, RawArray* data) : BaseMap(isolate, data) {} 592 UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
593 }; 593 };
594 594
595 595
596 template<typename KeyTraits> 596 template<typename KeyTraits>
597 class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > { 597 class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > {
598 public: 598 public:
599 typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap; 599 typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap;
600 explicit EnumIndexHashMap(RawArray* data) : BaseMap(data) {} 600 explicit EnumIndexHashMap(RawArray* data) : BaseMap(data) {}
601 EnumIndexHashMap(Isolate* isolate, RawArray* data) : BaseMap(isolate, data) {} 601 EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
602 }; 602 };
603 603
604 604
605 template<typename BaseIterTable> 605 template<typename BaseIterTable>
606 class HashSet : public BaseIterTable { 606 class HashSet : public BaseIterTable {
607 public: 607 public:
608 explicit HashSet(RawArray* data) : BaseIterTable(data) {} 608 explicit HashSet(RawArray* data) : BaseIterTable(data) {}
609 HashSet(Isolate* isolate, RawArray* data) : BaseIterTable(isolate, data) {} 609 HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
610 bool Insert(const Object& key) { 610 bool Insert(const Object& key) {
611 EnsureCapacity(); 611 EnsureCapacity();
612 intptr_t entry = -1; 612 intptr_t entry = -1;
613 bool present = BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry); 613 bool present = BaseIterTable::FindKeyOrDeletedOrUnused(key, &entry);
614 if (!present) { 614 if (!present) {
615 BaseIterTable::InsertKey(entry, key); 615 BaseIterTable::InsertKey(entry, key);
616 } 616 }
617 return present; 617 return present;
618 } 618 }
619 619
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this); 676 HashTables::EnsureLoadFactor(0.0, kMaxLoadFactor, *this);
677 } 677 }
678 }; 678 };
679 679
680 680
681 template<typename KeyTraits> 681 template<typename KeyTraits>
682 class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > { 682 class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
683 public: 683 public:
684 typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet; 684 typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
685 explicit UnorderedHashSet(RawArray* data) : BaseSet(data) {} 685 explicit UnorderedHashSet(RawArray* data) : BaseSet(data) {}
686 UnorderedHashSet(Isolate* isolate, RawArray* data) : BaseSet(isolate, data) {} 686 UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
687 }; 687 };
688 688
689 689
690 template<typename KeyTraits> 690 template<typename KeyTraits>
691 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > { 691 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > {
692 public: 692 public:
693 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet; 693 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet;
694 explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {} 694 explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {}
695 EnumIndexHashSet(Isolate* isolate, RawArray* data) : BaseSet(isolate, data) {} 695 EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
696 }; 696 };
697 697
698 } // namespace dart 698 } // namespace dart
699 699
700 #endif // VM_HASH_TABLE_H_ 700 #endif // VM_HASH_TABLE_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/symbols.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698