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

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
« runtime/vm/assembler_x64.h ('K') | « runtime/vm/flow_graph.h ('k') | no next file » | 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) 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(KeyValueTrait::NoValue()), 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 = KeyValueTrait::NoValue();
74 static_cast<typename KeyValueTrait::Value>(0);
75 81
76 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key)); 82 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key));
77 uword pos = Bound(hash); 83 uword pos = Bound(hash);
78 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) { 84 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
79 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) { 85 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
80 return KeyValueTrait::ValueOf(array_[pos].kv); 86 return KeyValueTrait::ValueOf(array_[pos].kv);
81 } 87 }
82 88
83 intptr_t next = array_[pos].next; 89 intptr_t next = array_[pos].next;
84 while (next != kNil) { 90 while (next != kNil) {
(...skipping 19 matching lines...) Expand all
104 lists_(Isolate::Current()->current_zone()-> 110 lists_(Isolate::Current()->current_zone()->
105 Alloc<HashMapListElement>(other.lists_size_)), 111 Alloc<HashMapListElement>(other.lists_size_)),
106 free_list_head_(other.free_list_head_) { 112 free_list_head_(other.free_list_head_) {
107 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement)); 113 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
108 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement)); 114 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
109 } 115 }
110 116
111 117
112 template <typename KeyValueTrait> 118 template <typename KeyValueTrait>
113 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) { 119 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
114 const typename KeyValueTrait::Value kNoValue = 120 const typename KeyValueTrait::Value kNoValue = KeyValueTrait::NoValue();
115 static_cast<typename KeyValueTrait::Value>(0);
116 121
117 ASSERT(new_size > count_); 122 ASSERT(new_size > count_);
118 // Hashing the values into the new array has no more collisions than in the 123 // 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. 124 // old hash map, so we can use the existing lists_ array, if we are careful.
120 125
121 // Make sure we have at least one free element. 126 // Make sure we have at least one free element.
122 if (free_list_head_ == kNil) { 127 if (free_list_head_ == kNil) {
123 ResizeLists(lists_size_ << 1); 128 ResizeLists(lists_size_ << 1);
124 } 129 }
125 130
126 HashMapListElement* new_array = 131 HashMapListElement* new_array =
127 Isolate::Current()->current_zone()->Alloc<HashMapListElement>(new_size); 132 Isolate::Current()->current_zone()->Alloc<HashMapListElement>(new_size);
128 memset(new_array, 0, sizeof(HashMapListElement) * new_size); 133 InitArray(new_array, new_size);
129 134
130 HashMapListElement* old_array = array_; 135 HashMapListElement* old_array = array_;
131 intptr_t old_size = array_size_; 136 intptr_t old_size = array_size_;
132 137
133 intptr_t old_count = count_; 138 intptr_t old_count = count_;
134 count_ = 0; 139 count_ = 0;
135 array_size_ = new_size; 140 array_size_ = new_size;
136 array_ = new_array; 141 array_ = new_array;
137 142
138 if (old_array != NULL) { 143 if (old_array != NULL) {
(...skipping 18 matching lines...) Expand all
157 } 162 }
158 163
159 164
160 template <typename T> 165 template <typename T>
161 void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) { 166 void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) {
162 ASSERT(new_size > lists_size_); 167 ASSERT(new_size > lists_size_);
163 168
164 HashMapListElement* new_lists = 169 HashMapListElement* new_lists =
165 Isolate::Current()->current_zone()-> 170 Isolate::Current()->current_zone()->
166 Alloc<HashMapListElement>(new_size); 171 Alloc<HashMapListElement>(new_size);
167 memset(new_lists, 0, sizeof(HashMapListElement) * new_size); 172 InitArray(new_lists, new_size);
168 173
169 HashMapListElement* old_lists = lists_; 174 HashMapListElement* old_lists = lists_;
170 intptr_t old_size = lists_size_; 175 intptr_t old_size = lists_size_;
171 176
172 lists_size_ = new_size; 177 lists_size_ = new_size;
173 lists_ = new_lists; 178 lists_ = new_lists;
174 179
175 if (old_lists != NULL) { 180 if (old_lists != NULL) {
176 memmove(lists_, old_lists, old_size * sizeof(HashMapListElement)); 181 memmove(lists_, old_lists, old_size * sizeof(HashMapListElement));
177 } 182 }
178 for (intptr_t i = old_size; i < lists_size_; ++i) { 183 for (intptr_t i = old_size; i < lists_size_; ++i) {
179 lists_[i].next = free_list_head_; 184 lists_[i].next = free_list_head_;
180 free_list_head_ = i; 185 free_list_head_ = i;
181 } 186 }
182 } 187 }
183 188
184 189
185 template <typename KeyValueTrait> 190 template <typename KeyValueTrait>
186 void DirectChainedHashMap<KeyValueTrait>:: 191 void DirectChainedHashMap<KeyValueTrait>::
187 Insert(typename KeyValueTrait::Pair kv) { 192 Insert(typename KeyValueTrait::Pair kv) {
188 const typename KeyValueTrait::Value kNoValue = 193 const typename KeyValueTrait::Value kNoValue = KeyValueTrait::NoValue();
189 static_cast<typename KeyValueTrait::Value>(0);
190 194
191 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue); 195 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue);
192 // Resizing when half of the hashtable is filled up. 196 // Resizing when half of the hashtable is filled up.
193 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1); 197 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
194 ASSERT(count_ < array_size_); 198 ASSERT(count_ < array_size_);
195 count_++; 199 count_++;
196 uword pos = Bound( 200 uword pos = Bound(
197 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv)))); 201 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv))));
198 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) { 202 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) {
199 array_[pos].kv = kv; 203 array_[pos].kv = kv;
(...skipping 22 matching lines...) Expand all
222 typedef T* Pair; 226 typedef T* Pair;
223 227
224 static Key KeyOf(Pair kv) { 228 static Key KeyOf(Pair kv) {
225 return kv; 229 return kv;
226 } 230 }
227 231
228 static Value ValueOf(Pair kv) { 232 static Value ValueOf(Pair kv) {
229 return kv; 233 return kv;
230 } 234 }
231 235
236 static Value NoValue() { return NULL; }
237
232 static inline intptr_t Hashcode(Key key) { 238 static inline intptr_t Hashcode(Key key) {
233 return key->Hashcode(); 239 return key->Hashcode();
234 } 240 }
235 241
236 static inline bool IsKeyEqual(Pair kv, Key key) { 242 static inline bool IsKeyEqual(Pair kv, Key key) {
237 return kv->Equals(key); 243 return kv->Equals(key);
238 } 244 }
239 }; 245 };
240 246
241 } // namespace dart 247 } // namespace dart
242 248
243 #endif // VM_HASH_MAP_H_ 249 #endif // VM_HASH_MAP_H_
OLDNEW
« runtime/vm/assembler_x64.h ('K') | « runtime/vm/flow_graph.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698