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

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

Issue 14326006: Optimize static field and context load/stores as part of CSE pass. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 // with a given hash. Colliding elements are stored in linked lists. 50 // with a given hash. Colliding elements are stored in linked lists.
51 HashMapListElement* lists_; // The linked lists containing hash collisions. 51 HashMapListElement* lists_; // The linked lists containing hash collisions.
52 intptr_t free_list_head_; // Unused elements in lists_ are on the free list. 52 intptr_t free_list_head_; // Unused elements in lists_ are on the free list.
53 }; 53 };
54 54
55 55
56 template <typename KeyValueTrait> 56 template <typename KeyValueTrait>
57 typename KeyValueTrait::Value 57 typename KeyValueTrait::Value
58 DirectChainedHashMap<KeyValueTrait>:: 58 DirectChainedHashMap<KeyValueTrait>::
59 Lookup(typename KeyValueTrait::Key key) const { 59 Lookup(typename KeyValueTrait::Key key) const {
60 const typename KeyValueTrait::Value kNoValue =
61 static_cast<typename KeyValueTrait::Value>(0);
62
60 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key)); 63 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key));
61 uword pos = Bound(hash); 64 uword pos = Bound(hash);
62 if (KeyValueTrait::ValueOf(array_[pos].kv) != NULL) { 65 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
63 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) { 66 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
64 return KeyValueTrait::ValueOf(array_[pos].kv); 67 return KeyValueTrait::ValueOf(array_[pos].kv);
65 } 68 }
66 69
67 intptr_t next = array_[pos].next; 70 intptr_t next = array_[pos].next;
68 while (next != kNil) { 71 while (next != kNil) {
69 if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) { 72 if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) {
70 return KeyValueTrait::ValueOf(lists_[next].kv); 73 return KeyValueTrait::ValueOf(lists_[next].kv);
71 } 74 }
72 next = lists_[next].next; 75 next = lists_[next].next;
73 } 76 }
74 } 77 }
75 return NULL; 78 return kNoValue;
76 } 79 }
77 80
78 81
79 template <typename KeyValueTrait> 82 template <typename KeyValueTrait>
80 DirectChainedHashMap<KeyValueTrait>:: 83 DirectChainedHashMap<KeyValueTrait>::
81 DirectChainedHashMap(const DirectChainedHashMap& other) 84 DirectChainedHashMap(const DirectChainedHashMap& other)
82 : ValueObject(), 85 : ValueObject(),
83 array_size_(other.array_size_), 86 array_size_(other.array_size_),
84 lists_size_(other.lists_size_), 87 lists_size_(other.lists_size_),
85 count_(other.count_), 88 count_(other.count_),
86 array_(Isolate::Current()->current_zone()-> 89 array_(Isolate::Current()->current_zone()->
87 Alloc<HashMapListElement>(other.array_size_)), 90 Alloc<HashMapListElement>(other.array_size_)),
88 lists_(Isolate::Current()->current_zone()-> 91 lists_(Isolate::Current()->current_zone()->
89 Alloc<HashMapListElement>(other.lists_size_)), 92 Alloc<HashMapListElement>(other.lists_size_)),
90 free_list_head_(other.free_list_head_) { 93 free_list_head_(other.free_list_head_) {
91 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement)); 94 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
92 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement)); 95 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
93 } 96 }
94 97
95 98
96 template <typename KeyValueTrait> 99 template <typename KeyValueTrait>
97 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) { 100 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
101 const typename KeyValueTrait::Value kNoValue =
102 static_cast<typename KeyValueTrait::Value>(0);
103
98 ASSERT(new_size > count_); 104 ASSERT(new_size > count_);
99 // Hashing the values into the new array has no more collisions than in the 105 // Hashing the values into the new array has no more collisions than in the
100 // old hash map, so we can use the existing lists_ array, if we are careful. 106 // old hash map, so we can use the existing lists_ array, if we are careful.
101 107
102 // Make sure we have at least one free element. 108 // Make sure we have at least one free element.
103 if (free_list_head_ == kNil) { 109 if (free_list_head_ == kNil) {
104 ResizeLists(lists_size_ << 1); 110 ResizeLists(lists_size_ << 1);
105 } 111 }
106 112
107 HashMapListElement* new_array = 113 HashMapListElement* new_array =
108 Isolate::Current()->current_zone()->Alloc<HashMapListElement>(new_size); 114 Isolate::Current()->current_zone()->Alloc<HashMapListElement>(new_size);
109 memset(new_array, 0, sizeof(HashMapListElement) * new_size); 115 memset(new_array, 0, sizeof(HashMapListElement) * new_size);
110 116
111 HashMapListElement* old_array = array_; 117 HashMapListElement* old_array = array_;
112 intptr_t old_size = array_size_; 118 intptr_t old_size = array_size_;
113 119
114 intptr_t old_count = count_; 120 intptr_t old_count = count_;
115 count_ = 0; 121 count_ = 0;
116 array_size_ = new_size; 122 array_size_ = new_size;
117 array_ = new_array; 123 array_ = new_array;
118 124
119 if (old_array != NULL) { 125 if (old_array != NULL) {
120 // Iterate over all the elements in lists, rehashing them. 126 // Iterate over all the elements in lists, rehashing them.
121 for (intptr_t i = 0; i < old_size; ++i) { 127 for (intptr_t i = 0; i < old_size; ++i) {
122 if (KeyValueTrait::ValueOf(old_array[i].kv) != NULL) { 128 if (KeyValueTrait::ValueOf(old_array[i].kv) != kNoValue) {
123 intptr_t current = old_array[i].next; 129 intptr_t current = old_array[i].next;
124 while (current != kNil) { 130 while (current != kNil) {
125 Insert(lists_[current].kv); 131 Insert(lists_[current].kv);
126 intptr_t next = lists_[current].next; 132 intptr_t next = lists_[current].next;
127 lists_[current].next = free_list_head_; 133 lists_[current].next = free_list_head_;
128 free_list_head_ = current; 134 free_list_head_ = current;
129 current = next; 135 current = next;
130 } 136 }
131 // Rehash the directly stored value. 137 // Rehash the directly stored value.
132 Insert(old_array[i].kv); 138 Insert(old_array[i].kv);
(...skipping 26 matching lines...) Expand all
159 for (intptr_t i = old_size; i < lists_size_; ++i) { 165 for (intptr_t i = old_size; i < lists_size_; ++i) {
160 lists_[i].next = free_list_head_; 166 lists_[i].next = free_list_head_;
161 free_list_head_ = i; 167 free_list_head_ = i;
162 } 168 }
163 } 169 }
164 170
165 171
166 template <typename KeyValueTrait> 172 template <typename KeyValueTrait>
167 void DirectChainedHashMap<KeyValueTrait>:: 173 void DirectChainedHashMap<KeyValueTrait>::
168 Insert(typename KeyValueTrait::Pair kv) { 174 Insert(typename KeyValueTrait::Pair kv) {
169 ASSERT(KeyValueTrait::ValueOf(kv) != NULL); 175 const typename KeyValueTrait::Value kNoValue =
176 static_cast<typename KeyValueTrait::Value>(0);
177
178 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue);
170 // Resizing when half of the hashtable is filled up. 179 // Resizing when half of the hashtable is filled up.
171 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1); 180 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
172 ASSERT(count_ < array_size_); 181 ASSERT(count_ < array_size_);
173 count_++; 182 count_++;
174 uword pos = Bound( 183 uword pos = Bound(
175 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv)))); 184 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv))));
176 if (KeyValueTrait::ValueOf(array_[pos].kv) == NULL) { 185 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) {
177 array_[pos].kv = kv; 186 array_[pos].kv = kv;
178 array_[pos].next = kNil; 187 array_[pos].next = kNil;
179 } else { 188 } else {
180 if (free_list_head_ == kNil) { 189 if (free_list_head_ == kNil) {
181 ResizeLists(lists_size_ << 1); 190 ResizeLists(lists_size_ << 1);
182 } 191 }
183 intptr_t new_element_pos = free_list_head_; 192 intptr_t new_element_pos = free_list_head_;
184 ASSERT(new_element_pos != kNil); 193 ASSERT(new_element_pos != kNil);
185 free_list_head_ = lists_[free_list_head_].next; 194 free_list_head_ = lists_[free_list_head_].next;
186 lists_[new_element_pos].kv = kv; 195 lists_[new_element_pos].kv = kv;
187 lists_[new_element_pos].next = array_[pos].next; 196 lists_[new_element_pos].next = array_[pos].next;
188 ASSERT(array_[pos].next == kNil || 197 ASSERT(array_[pos].next == kNil ||
189 KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != NULL); 198 KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != kNoValue);
190 array_[pos].next = new_element_pos; 199 array_[pos].next = new_element_pos;
191 } 200 }
192 } 201 }
193 202
194 203
195 template<typename T> 204 template<typename T>
196 class PointerKeyValueTrait { 205 class PointerKeyValueTrait {
197 public: 206 public:
198 typedef T* Value; 207 typedef T* Value;
199 typedef T* Key; 208 typedef T* Key;
(...skipping 12 matching lines...) Expand all
212 } 221 }
213 222
214 static inline bool IsKeyEqual(Pair kv, Key key) { 223 static inline bool IsKeyEqual(Pair kv, Key key) {
215 return kv->Equals(key); 224 return kv->Equals(key);
216 } 225 }
217 }; 226 };
218 227
219 } // namespace dart 228 } // namespace dart
220 229
221 #endif // VM_HASH_MAP_H_ 230 #endif // VM_HASH_MAP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698