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

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

Issue 848703002: Improve constant pool implementation in the assembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_MAP_H_ 5 #ifndef VM_HASH_MAP_H_
6 #define VM_HASH_MAP_H_ 6 #define VM_HASH_MAP_H_
7 7
8 namespace dart { 8 namespace dart {
9 9
10 template <typename KeyValueTrait> 10 template <typename KeyValueTrait>
(...skipping 13 matching lines...) Expand all
24 24
25 void Insert(typename KeyValueTrait::Pair kv); 25 void Insert(typename KeyValueTrait::Pair kv);
26 26
27 typename KeyValueTrait::Value Lookup(typename KeyValueTrait::Key key) const; 27 typename KeyValueTrait::Value Lookup(typename KeyValueTrait::Key key) const;
28 28
29 bool IsEmpty() const { return count_ == 0; } 29 bool IsEmpty() const { return count_ == 0; }
30 30
31 void Clear() { 31 void Clear() {
32 if (!IsEmpty()) { 32 if (!IsEmpty()) {
33 count_ = 0; 33 count_ = 0;
34 memset(array_, 0, sizeof(HashMapListElement) * array_size_); 34 InitArray(array_, array_size_);
35 memset(lists_, 0, sizeof(HashMapListElement) * lists_size_); 35 InitArray(lists_, lists_size_);
36 lists_[0].next = kNil; 36 lists_[0].next = kNil;
37 for (intptr_t i = 1; i < lists_size_; ++i) { 37 for (intptr_t i = 1; i < lists_size_; ++i) {
38 lists_[i].next = i - 1; 38 lists_[i].next = i - 1;
39 } 39 }
40 free_list_head_ = lists_size_ - 1; 40 free_list_head_ = lists_size_ - 1;
41 } 41 }
42 } 42 }
43 43
44 protected: 44 protected:
45 // A linked list of T values. Stored in arrays. 45 // A linked list of T values. Stored in arrays.
46 struct HashMapListElement { 46 struct HashMapListElement {
47 HashMapListElement() : kv(), next(kNil) { }
47 typename KeyValueTrait::Pair kv; 48 typename KeyValueTrait::Pair kv;
48 intptr_t next; // Index in the array of the next list element. 49 intptr_t next; // Index in the array of the next list element.
49 }; 50 };
50 static const intptr_t kNil = -1; // The end of a linked list 51 static const intptr_t kNil = -1; // The end of a linked list
51 52
53 static void InitArray(HashMapListElement* array, intptr_t size) {
54 for (intptr_t i = 0; i < size; ++i) {
55 array[i] = HashMapListElement();
56 }
57 }
58
52 // Must be a power of 2. 59 // Must be a power of 2.
53 static const intptr_t kInitialSize = 16; 60 static const intptr_t kInitialSize = 16;
54 61
55 void Resize(intptr_t new_size); 62 void Resize(intptr_t new_size);
56 void ResizeLists(intptr_t new_size); 63 void ResizeLists(intptr_t new_size);
57 uword Bound(uword value) const { return value & (array_size_ - 1); } 64 uword Bound(uword value) const { return value & (array_size_ - 1); }
58 65
59 intptr_t array_size_; 66 intptr_t array_size_;
60 intptr_t lists_size_; 67 intptr_t lists_size_;
61 intptr_t count_; // The number of values stored in the HashMap. 68 intptr_t count_; // The number of values stored in the HashMap.
62 HashMapListElement* array_; // Primary store - contains the first value 69 HashMapListElement* array_; // Primary store - contains the first value
63 // with a given hash. Colliding elements are stored in linked lists. 70 // with a given hash. Colliding elements are stored in linked lists.
64 HashMapListElement* lists_; // The linked lists containing hash collisions. 71 HashMapListElement* lists_; // The linked lists containing hash collisions.
65 intptr_t free_list_head_; // Unused elements in lists_ are on the free list. 72 intptr_t free_list_head_; // Unused elements in lists_ are on the free list.
66 }; 73 };
67 74
68 75
69 template <typename KeyValueTrait> 76 template <typename KeyValueTrait>
70 typename KeyValueTrait::Value 77 typename KeyValueTrait::Value
71 DirectChainedHashMap<KeyValueTrait>:: 78 DirectChainedHashMap<KeyValueTrait>::
72 Lookup(typename KeyValueTrait::Key key) const { 79 Lookup(typename KeyValueTrait::Key key) const {
73 const typename KeyValueTrait::Value kNoValue = 80 const typename KeyValueTrait::Value kNoValue =
74 static_cast<typename KeyValueTrait::Value>(0); 81 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
75 82
76 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key)); 83 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key));
77 uword pos = Bound(hash); 84 uword pos = Bound(hash);
78 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) { 85 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
79 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) { 86 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
80 return KeyValueTrait::ValueOf(array_[pos].kv); 87 return KeyValueTrait::ValueOf(array_[pos].kv);
81 } 88 }
82 89
83 intptr_t next = array_[pos].next; 90 intptr_t next = array_[pos].next;
84 while (next != kNil) { 91 while (next != kNil) {
(...skipping 20 matching lines...) Expand all
105 Alloc<HashMapListElement>(other.lists_size_)), 112 Alloc<HashMapListElement>(other.lists_size_)),
106 free_list_head_(other.free_list_head_) { 113 free_list_head_(other.free_list_head_) {
107 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement)); 114 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
108 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement)); 115 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
109 } 116 }
110 117
111 118
112 template <typename KeyValueTrait> 119 template <typename KeyValueTrait>
113 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) { 120 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
114 const typename KeyValueTrait::Value kNoValue = 121 const typename KeyValueTrait::Value kNoValue =
115 static_cast<typename KeyValueTrait::Value>(0); 122 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
116 123
117 ASSERT(new_size > count_); 124 ASSERT(new_size > count_);
118 // Hashing the values into the new array has no more collisions than in the 125 // Hashing the values into the new array has no more collisions than in the
119 // old hash map, so we can use the existing lists_ array, if we are careful. 126 // old hash map, so we can use the existing lists_ array, if we are careful.
120 127
121 // Make sure we have at least one free element. 128 // Make sure we have at least one free element.
122 if (free_list_head_ == kNil) { 129 if (free_list_head_ == kNil) {
123 ResizeLists(lists_size_ << 1); 130 ResizeLists(lists_size_ << 1);
124 } 131 }
125 132
126 HashMapListElement* new_array = 133 HashMapListElement* new_array =
127 Isolate::Current()->current_zone()->Alloc<HashMapListElement>(new_size); 134 Isolate::Current()->current_zone()->Alloc<HashMapListElement>(new_size);
128 memset(new_array, 0, sizeof(HashMapListElement) * new_size); 135 InitArray(new_array, new_size);
129 136
130 HashMapListElement* old_array = array_; 137 HashMapListElement* old_array = array_;
131 intptr_t old_size = array_size_; 138 intptr_t old_size = array_size_;
132 139
133 intptr_t old_count = count_; 140 intptr_t old_count = count_;
134 count_ = 0; 141 count_ = 0;
135 array_size_ = new_size; 142 array_size_ = new_size;
136 array_ = new_array; 143 array_ = new_array;
137 144
138 if (old_array != NULL) { 145 if (old_array != NULL) {
(...skipping 18 matching lines...) Expand all
157 } 164 }
158 165
159 166
160 template <typename T> 167 template <typename T>
161 void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) { 168 void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) {
162 ASSERT(new_size > lists_size_); 169 ASSERT(new_size > lists_size_);
163 170
164 HashMapListElement* new_lists = 171 HashMapListElement* new_lists =
165 Isolate::Current()->current_zone()-> 172 Isolate::Current()->current_zone()->
166 Alloc<HashMapListElement>(new_size); 173 Alloc<HashMapListElement>(new_size);
167 memset(new_lists, 0, sizeof(HashMapListElement) * new_size); 174 InitArray(new_lists, new_size);
168 175
169 HashMapListElement* old_lists = lists_; 176 HashMapListElement* old_lists = lists_;
170 intptr_t old_size = lists_size_; 177 intptr_t old_size = lists_size_;
171 178
172 lists_size_ = new_size; 179 lists_size_ = new_size;
173 lists_ = new_lists; 180 lists_ = new_lists;
174 181
175 if (old_lists != NULL) { 182 if (old_lists != NULL) {
176 memmove(lists_, old_lists, old_size * sizeof(HashMapListElement)); 183 memmove(lists_, old_lists, old_size * sizeof(HashMapListElement));
177 } 184 }
178 for (intptr_t i = old_size; i < lists_size_; ++i) { 185 for (intptr_t i = old_size; i < lists_size_; ++i) {
179 lists_[i].next = free_list_head_; 186 lists_[i].next = free_list_head_;
180 free_list_head_ = i; 187 free_list_head_ = i;
181 } 188 }
182 } 189 }
183 190
184 191
185 template <typename KeyValueTrait> 192 template <typename KeyValueTrait>
186 void DirectChainedHashMap<KeyValueTrait>:: 193 void DirectChainedHashMap<KeyValueTrait>::
187 Insert(typename KeyValueTrait::Pair kv) { 194 Insert(typename KeyValueTrait::Pair kv) {
188 const typename KeyValueTrait::Value kNoValue = 195 const typename KeyValueTrait::Value kNoValue =
189 static_cast<typename KeyValueTrait::Value>(0); 196 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
190 197
191 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue); 198 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue);
192 // Resizing when half of the hashtable is filled up. 199 // Resizing when half of the hashtable is filled up.
193 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1); 200 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
194 ASSERT(count_ < array_size_); 201 ASSERT(count_ < array_size_);
195 count_++; 202 count_++;
196 uword pos = Bound( 203 uword pos = Bound(
197 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv)))); 204 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv))));
198 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) { 205 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) {
199 array_[pos].kv = kv; 206 array_[pos].kv = kv;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 241 }
235 242
236 static inline bool IsKeyEqual(Pair kv, Key key) { 243 static inline bool IsKeyEqual(Pair kv, Key key) {
237 return kv->Equals(key); 244 return kv->Equals(key);
238 } 245 }
239 }; 246 };
240 247
241 } // namespace dart 248 } // namespace dart
242 249
243 #endif // VM_HASH_MAP_H_ 250 #endif // VM_HASH_MAP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698