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

Side by Side Diff: src/hashmap.h

Issue 9691040: Ensure that generated code for object literals will call Runtime_DefineOrRedefineAccessorProperty o… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased and incorporated review comments Created 8 years, 9 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 18 matching lines...) Expand all
29 #define V8_HASHMAP_H_ 29 #define V8_HASHMAP_H_
30 30
31 #include "allocation.h" 31 #include "allocation.h"
32 #include "checks.h" 32 #include "checks.h"
33 #include "utils.h" 33 #include "utils.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 template<class AllocationPolicy> 38 template<class AllocationPolicy>
39 class TemplateHashMap { 39 class TemplateHashMapImpl {
40 public: 40 public:
41 typedef bool (*MatchFun) (void* key1, void* key2); 41 typedef bool (*MatchFun) (void* key1, void* key2);
42 42
43 // initial_capacity is the size of the initial hash map; 43 // initial_capacity is the size of the initial hash map;
44 // it must be a power of 2 (and thus must not be 0). 44 // it must be a power of 2 (and thus must not be 0).
45 TemplateHashMap(MatchFun match, uint32_t initial_capacity = 8); 45 TemplateHashMapImpl(MatchFun match, uint32_t initial_capacity = 8);
46 46
47 ~TemplateHashMap(); 47 ~TemplateHashMapImpl();
48 48
49 // HashMap entries are (key, value, hash) triplets. 49 // HashMap entries are (key, value, hash) triplets.
50 // Some clients may not need to use the value slot 50 // Some clients may not need to use the value slot
51 // (e.g. implementers of sets, where the key is the value). 51 // (e.g. implementers of sets, where the key is the value).
52 struct Entry { 52 struct Entry {
53 void* key; 53 void* key;
54 void* value; 54 void* value;
55 uint32_t hash; // the full hash value for key 55 uint32_t hash; // the full hash value for key
56 }; 56 };
57 57
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 Entry* map_; 92 Entry* map_;
93 uint32_t capacity_; 93 uint32_t capacity_;
94 uint32_t occupancy_; 94 uint32_t occupancy_;
95 95
96 Entry* map_end() const { return map_ + capacity_; } 96 Entry* map_end() const { return map_ + capacity_; }
97 Entry* Probe(void* key, uint32_t hash); 97 Entry* Probe(void* key, uint32_t hash);
98 void Initialize(uint32_t capacity); 98 void Initialize(uint32_t capacity);
99 void Resize(); 99 void Resize();
100 }; 100 };
101 101
102 typedef TemplateHashMap<FreeStoreAllocationPolicy> HashMap; 102 typedef TemplateHashMapImpl<FreeStoreAllocationPolicy> HashMap;
103 103
104 template<class P> 104 template<class P>
105 TemplateHashMap<P>::TemplateHashMap(MatchFun match, 105 TemplateHashMapImpl<P>::TemplateHashMapImpl(MatchFun match,
106 uint32_t initial_capacity) { 106 uint32_t initial_capacity) {
107 match_ = match; 107 match_ = match;
108 Initialize(initial_capacity); 108 Initialize(initial_capacity);
109 } 109 }
110 110
111 111
112 template<class P> 112 template<class P>
113 TemplateHashMap<P>::~TemplateHashMap() { 113 TemplateHashMapImpl<P>::~TemplateHashMapImpl() {
114 P::Delete(map_); 114 P::Delete(map_);
115 } 115 }
116 116
117 117
118 template<class P> 118 template<class P>
119 typename TemplateHashMap<P>::Entry* TemplateHashMap<P>::Lookup( 119 typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Lookup(
120 void* key, uint32_t hash, bool insert) { 120 void* key, uint32_t hash, bool insert) {
121 // Find a matching entry. 121 // Find a matching entry.
122 Entry* p = Probe(key, hash); 122 Entry* p = Probe(key, hash);
123 if (p->key != NULL) { 123 if (p->key != NULL) {
124 return p; 124 return p;
125 } 125 }
126 126
127 // No entry found; insert one if necessary. 127 // No entry found; insert one if necessary.
128 if (insert) { 128 if (insert) {
129 p->key = key; 129 p->key = key;
130 p->value = NULL; 130 p->value = NULL;
131 p->hash = hash; 131 p->hash = hash;
132 occupancy_++; 132 occupancy_++;
133 133
134 // Grow the map if we reached >= 80% occupancy. 134 // Grow the map if we reached >= 80% occupancy.
135 if (occupancy_ + occupancy_/4 >= capacity_) { 135 if (occupancy_ + occupancy_/4 >= capacity_) {
136 Resize(); 136 Resize();
137 p = Probe(key, hash); 137 p = Probe(key, hash);
138 } 138 }
139 139
140 return p; 140 return p;
141 } 141 }
142 142
143 // No entry found and none inserted. 143 // No entry found and none inserted.
144 return NULL; 144 return NULL;
145 } 145 }
146 146
147 147
148 template<class P> 148 template<class P>
149 void TemplateHashMap<P>::Remove(void* key, uint32_t hash) { 149 void TemplateHashMapImpl<P>::Remove(void* key, uint32_t hash) {
150 // Lookup the entry for the key to remove. 150 // Lookup the entry for the key to remove.
151 Entry* p = Probe(key, hash); 151 Entry* p = Probe(key, hash);
152 if (p->key == NULL) { 152 if (p->key == NULL) {
153 // Key not found nothing to remove. 153 // Key not found nothing to remove.
154 return; 154 return;
155 } 155 }
156 156
157 // To remove an entry we need to ensure that it does not create an empty 157 // To remove an entry we need to ensure that it does not create an empty
158 // entry that will cause the search for another entry to stop too soon. If all 158 // entry that will cause the search for another entry to stop too soon. If all
159 // the entries between the entry to remove and the next empty slot have their 159 // the entries between the entry to remove and the next empty slot have their
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } 199 }
200 } 200 }
201 201
202 // Clear the entry which is allowed to en emptied. 202 // Clear the entry which is allowed to en emptied.
203 p->key = NULL; 203 p->key = NULL;
204 occupancy_--; 204 occupancy_--;
205 } 205 }
206 206
207 207
208 template<class P> 208 template<class P>
209 void TemplateHashMap<P>::Clear() { 209 void TemplateHashMapImpl<P>::Clear() {
210 // Mark all entries as empty. 210 // Mark all entries as empty.
211 const Entry* end = map_end(); 211 const Entry* end = map_end();
212 for (Entry* p = map_; p < end; p++) { 212 for (Entry* p = map_; p < end; p++) {
213 p->key = NULL; 213 p->key = NULL;
214 } 214 }
215 occupancy_ = 0; 215 occupancy_ = 0;
216 } 216 }
217 217
218 218
219 template<class P> 219 template<class P>
220 typename TemplateHashMap<P>::Entry* TemplateHashMap<P>::Start() const { 220 typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Start() const {
221 return Next(map_ - 1); 221 return Next(map_ - 1);
222 } 222 }
223 223
224 224
225 template<class P> 225 template<class P>
226 typename TemplateHashMap<P>::Entry* TemplateHashMap<P>::Next(Entry* p) const { 226 typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Next(Entry* p)
227 const {
227 const Entry* end = map_end(); 228 const Entry* end = map_end();
228 ASSERT(map_ - 1 <= p && p < end); 229 ASSERT(map_ - 1 <= p && p < end);
229 for (p++; p < end; p++) { 230 for (p++; p < end; p++) {
230 if (p->key != NULL) { 231 if (p->key != NULL) {
231 return p; 232 return p;
232 } 233 }
233 } 234 }
234 return NULL; 235 return NULL;
235 } 236 }
236 237
237 238
238 template<class P> 239 template<class P>
239 typename TemplateHashMap<P>::Entry* TemplateHashMap<P>::Probe(void* key, 240 typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Probe(void* key,
240 uint32_t hash) { 241 uint32_t hash) {
241 ASSERT(key != NULL); 242 ASSERT(key != NULL);
242 243
243 ASSERT(IsPowerOf2(capacity_)); 244 ASSERT(IsPowerOf2(capacity_));
244 Entry* p = map_ + (hash & (capacity_ - 1)); 245 Entry* p = map_ + (hash & (capacity_ - 1));
245 const Entry* end = map_end(); 246 const Entry* end = map_end();
246 ASSERT(map_ <= p && p < end); 247 ASSERT(map_ <= p && p < end);
247 248
248 ASSERT(occupancy_ < capacity_); // Guarantees loop termination. 249 ASSERT(occupancy_ < capacity_); // Guarantees loop termination.
249 while (p->key != NULL && (hash != p->hash || !match_(key, p->key))) { 250 while (p->key != NULL && (hash != p->hash || !match_(key, p->key))) {
250 p++; 251 p++;
251 if (p >= end) { 252 if (p >= end) {
252 p = map_; 253 p = map_;
253 } 254 }
254 } 255 }
255 256
256 return p; 257 return p;
257 } 258 }
258 259
259 260
260 template<class P> 261 template<class P>
261 void TemplateHashMap<P>::Initialize(uint32_t capacity) { 262 void TemplateHashMapImpl<P>::Initialize(uint32_t capacity) {
262 ASSERT(IsPowerOf2(capacity)); 263 ASSERT(IsPowerOf2(capacity));
263 map_ = reinterpret_cast<Entry*>(P::New(capacity * sizeof(Entry))); 264 map_ = reinterpret_cast<Entry*>(P::New(capacity * sizeof(Entry)));
264 if (map_ == NULL) { 265 if (map_ == NULL) {
265 v8::internal::FatalProcessOutOfMemory("HashMap::Initialize"); 266 v8::internal::FatalProcessOutOfMemory("HashMap::Initialize");
266 return; 267 return;
267 } 268 }
268 capacity_ = capacity; 269 capacity_ = capacity;
269 Clear(); 270 Clear();
270 } 271 }
271 272
272 273
273 template<class P> 274 template<class P>
274 void TemplateHashMap<P>::Resize() { 275 void TemplateHashMapImpl<P>::Resize() {
275 Entry* map = map_; 276 Entry* map = map_;
276 uint32_t n = occupancy_; 277 uint32_t n = occupancy_;
277 278
278 // Allocate larger map. 279 // Allocate larger map.
279 Initialize(capacity_ * 2); 280 Initialize(capacity_ * 2);
280 281
281 // Rehash all current entries. 282 // Rehash all current entries.
282 for (Entry* p = map; n > 0; p++) { 283 for (Entry* p = map; n > 0; p++) {
283 if (p->key != NULL) { 284 if (p->key != NULL) {
284 Lookup(p->key, p->hash, true)->value = p->value; 285 Lookup(p->key, p->hash, true)->value = p->value;
285 n--; 286 n--;
286 } 287 }
287 } 288 }
288 289
289 // Delete old map. 290 // Delete old map.
290 P::Delete(map); 291 P::Delete(map);
291 } 292 }
292 293
294
295 // A hash map for pointer keys and values with an STL-like interface.
296 template<class Key, class Value, class AllocationPolicy>
297 class TemplateHashMap: private TemplateHashMapImpl<AllocationPolicy> {
298 public:
299 STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT
300 STATIC_ASSERT(sizeof(Value*) == sizeof(void*)); // NOLINT
301 struct value_type {
rossberg 2012/03/14 16:29:03 Hm, value_type doesn't seem to fit. I'd call this
Sven Panne 2012/03/15 07:12:57 The whole point of this finger exercise was to be
302 Key* first;
303 Value* second;
304 };
305
306 class Iterator {
307 public:
308 Iterator& operator++() {
309 entry_ = map_->Next(entry_);
310 return *this;
311 }
312
313 value_type* operator->() { return reinterpret_cast<value_type*>(entry_); }
314 bool operator!=(const Iterator& other) { return entry_ != other.entry_; }
315
316 private:
317 Iterator(const TemplateHashMapImpl<AllocationPolicy>* map,
318 typename TemplateHashMapImpl<AllocationPolicy>::Entry* entry) :
319 map_(map), entry_(entry) { }
320
321 const TemplateHashMapImpl<AllocationPolicy>* map_;
322 typename TemplateHashMapImpl<AllocationPolicy>::Entry* entry_;
323
324 friend class TemplateHashMap;
325 };
326
327 TemplateHashMap(
328 typename TemplateHashMapImpl<AllocationPolicy>::MatchFun match)
329 : TemplateHashMapImpl<AllocationPolicy>(match) { }
330
331 Iterator begin() const { return Iterator(this, this->Start()); }
332 Iterator end() const { return Iterator(this, NULL); }
333 Iterator find(Key* key, bool insert = false) {
334 return Iterator(this, Lookup(key, key->Hash(), insert));
335 }
336 };
337
293 } } // namespace v8::internal 338 } } // namespace v8::internal
294 339
295 #endif // V8_HASHMAP_H_ 340 #endif // V8_HASHMAP_H_
OLDNEW
« src/full-codegen.h ('K') | « src/full-codegen.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698