Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 // The reason we write our own hash map instead of using unordered_map in STL, | 5 // The reason we write our own hash map instead of using unordered_map in STL, | 
| 6 // is that STL containers use a mutex pool on debug build, which will lead to | 6 // is that STL containers use a mutex pool on debug build, which will lead to | 
| 7 // deadlock when we are using async signal handler. | 7 // deadlock when we are using async signal handler. | 
| 8 | 8 | 
| 9 #ifndef V8_BASE_HASHMAP_H_ | 9 #ifndef V8_BASE_HASHMAP_H_ | 
| 10 #define V8_BASE_HASHMAP_H_ | 10 #define V8_BASE_HASHMAP_H_ | 
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 class AllocationPolicy> | 262 class AllocationPolicy> | 
| 263 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* | 263 typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* | 
| 264 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Probe( | 264 TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Probe( | 
| 265 const Key& key, uint32_t hash) const { | 265 const Key& key, uint32_t hash) const { | 
| 266 DCHECK(base::bits::IsPowerOfTwo32(capacity_)); | 266 DCHECK(base::bits::IsPowerOfTwo32(capacity_)); | 
| 267 Entry* entry = map_ + (hash & (capacity_ - 1)); | 267 Entry* entry = map_ + (hash & (capacity_ - 1)); | 
| 268 const Entry* end = map_end(); | 268 const Entry* end = map_end(); | 
| 269 DCHECK(map_ <= entry && entry < end); | 269 DCHECK(map_ <= entry && entry < end); | 
| 270 | 270 | 
| 271 DCHECK(occupancy_ < capacity_); // Guarantees loop termination. | 271 DCHECK(occupancy_ < capacity_); // Guarantees loop termination. | 
| 272 while (entry->exists() && (hash != entry->hash || !match_(key, entry->key))) { | 272 while (entry->exists() && !match_(hash, entry->hash, key, entry->key)) { | 
| 273 entry++; | 273 entry++; | 
| 274 if (entry >= end) { | 274 if (entry >= end) { | 
| 275 entry = map_; | 275 entry = map_; | 
| 276 } | 276 } | 
| 277 } | 277 } | 
| 278 | 278 | 
| 279 return entry; | 279 return entry; | 
| 280 } | 280 } | 
| 281 | 281 | 
| 282 template <typename Key, typename Value, typename MatchFun, | 282 template <typename Key, typename Value, typename MatchFun, | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 new_entry = FillEmptyEntry(new_entry, entry->key, entry->value, | 330 new_entry = FillEmptyEntry(new_entry, entry->key, entry->value, | 
| 331 entry->hash, allocator); | 331 entry->hash, allocator); | 
| 332 n--; | 332 n--; | 
| 333 } | 333 } | 
| 334 } | 334 } | 
| 335 | 335 | 
| 336 // Delete old map. | 336 // Delete old map. | 
| 337 AllocationPolicy::Delete(map); | 337 AllocationPolicy::Delete(map); | 
| 338 } | 338 } | 
| 339 | 339 | 
| 340 // Match function which compares hashes before executing a (potentially | |
| 341 // expensive) key comparison. | |
| 342 template <typename Key, typename MatchFun> | |
| 343 struct HashKeyComp { | |
| 
 
rmcilroy
2016/09/30 16:07:15
Not sure on the name, how about HashEqualityThenKe
 
Leszek Swirski
2016/10/03 14:33:27
Neither could I, so done.
 
 | |
| 344 explicit HashKeyComp(MatchFun match) : match_(match) {} | |
| 345 | |
| 346 bool operator()(uint32_t hash1, uint32_t hash2, const Key& key1, | |
| 347 const Key& key2) const { | |
| 348 return hash1 == hash2 && match_(key1, key2); | |
| 349 } | |
| 350 | |
| 351 private: | |
| 352 MatchFun match_; | |
| 353 }; | |
| 354 | |
| 355 // Match function which compares keys directly by equality. | |
| 356 template <typename Key> | |
| 357 struct KeyEqual { | |
| 
 
rmcilroy
2016/09/30 16:07:15
nit - KeyEqualityMatcher (also move down to just a
 
Leszek Swirski
2016/10/03 14:33:27
Done.
 
 | |
| 358 bool operator()(uint32_t hash1, uint32_t hash2, const Key& key1, | |
| 359 const Key& key2) const { | |
| 360 return key1 == key2; | |
| 361 } | |
| 362 }; | |
| 363 | |
| 364 // Hashmap<void*, void*> which takes a custom key comparison function pointer. | |
| 340 template <typename AllocationPolicy> | 365 template <typename AllocationPolicy> | 
| 341 class CustomMatcherTemplateHashMapImpl | 366 class CustomMatcherTemplateHashMapImpl | 
| 342 : public TemplateHashMapImpl<void*, void*, bool (*)(void*, void*), | 367 : public TemplateHashMapImpl<void*, void*, | 
| 368 HashKeyComp<void*, bool (*)(void*, void*)>, | |
| 343 AllocationPolicy> { | 369 AllocationPolicy> { | 
| 344 typedef TemplateHashMapImpl<void*, void*, bool (*)(void*, void*), | 370 typedef TemplateHashMapImpl<void*, void*, | 
| 371 HashKeyComp<void*, bool (*)(void*, void*)>, | |
| 345 AllocationPolicy> | 372 AllocationPolicy> | 
| 346 Base; | 373 Base; | 
| 347 | 374 | 
| 348 public: | 375 public: | 
| 349 typedef bool (*MatchFun)(void*, void*); | 376 typedef bool (*MatchFun)(void*, void*); | 
| 350 | 377 | 
| 351 CustomMatcherTemplateHashMapImpl( | 378 CustomMatcherTemplateHashMapImpl( | 
| 352 MatchFun match, uint32_t capacity = Base::kDefaultHashMapCapacity, | 379 MatchFun match, uint32_t capacity = Base::kDefaultHashMapCapacity, | 
| 353 AllocationPolicy allocator = AllocationPolicy()) | 380 AllocationPolicy allocator = AllocationPolicy()) | 
| 354 : Base(capacity, match, allocator) {} | 381 : Base(capacity, HashKeyComp<void*, MatchFun>(match), allocator) {} | 
| 355 }; | 382 }; | 
| 356 | 383 | 
| 357 typedef CustomMatcherTemplateHashMapImpl<DefaultAllocationPolicy> | 384 typedef CustomMatcherTemplateHashMapImpl<DefaultAllocationPolicy> | 
| 358 CustomMatcherHashMap; | 385 CustomMatcherHashMap; | 
| 359 | 386 | 
| 387 // Hashmap<void*, void*> which compares the key pointers directly. | |
| 360 template <typename AllocationPolicy> | 388 template <typename AllocationPolicy> | 
| 361 class PointerTemplateHashMapImpl | 389 class PointerTemplateHashMapImpl | 
| 362 : public TemplateHashMapImpl<void*, void*, std::equal_to<void*>, | 390 : public TemplateHashMapImpl<void*, void*, KeyEqual<void*>, | 
| 363 AllocationPolicy> { | 391 AllocationPolicy> { | 
| 364 typedef TemplateHashMapImpl<void*, void*, std::equal_to<void*>, | 392 typedef TemplateHashMapImpl<void*, void*, KeyEqual<void*>, AllocationPolicy> | 
| 365 AllocationPolicy> | |
| 366 Base; | 393 Base; | 
| 367 | 394 | 
| 368 public: | 395 public: | 
| 369 PointerTemplateHashMapImpl(uint32_t capacity = Base::kDefaultHashMapCapacity, | 396 PointerTemplateHashMapImpl(uint32_t capacity = Base::kDefaultHashMapCapacity, | 
| 370 AllocationPolicy allocator = AllocationPolicy()) | 397 AllocationPolicy allocator = AllocationPolicy()) | 
| 371 : Base(capacity, std::equal_to<void*>(), allocator) {} | 398 : Base(capacity, KeyEqual<void*>(), allocator) {} | 
| 372 }; | 399 }; | 
| 373 | 400 | 
| 374 typedef PointerTemplateHashMapImpl<DefaultAllocationPolicy> HashMap; | 401 typedef PointerTemplateHashMapImpl<DefaultAllocationPolicy> HashMap; | 
| 375 | 402 | 
| 376 // A hash map for pointer keys and values with an STL-like interface. | 403 // A hash map for pointer keys and values with an STL-like interface. | 
| 377 template <class Key, class Value, class MatchFun, class AllocationPolicy> | 404 template <class Key, class Value, class MatchFun, class AllocationPolicy> | 
| 378 class TemplateHashMap | 405 class TemplateHashMap | 
| 379 : private TemplateHashMapImpl<void*, void*, MatchFun, AllocationPolicy> { | 406 : private TemplateHashMapImpl<void*, void*, HashKeyComp<void*, MatchFun>, | 
| 380 typedef TemplateHashMapImpl<void*, void*, MatchFun, AllocationPolicy> Base; | 407 AllocationPolicy> { | 
| 408 typedef TemplateHashMapImpl<void*, void*, HashKeyComp<void*, MatchFun>, | |
| 409 AllocationPolicy> | |
| 410 Base; | |
| 381 | 411 | 
| 382 public: | 412 public: | 
| 383 STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT | 413 STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT | 
| 384 STATIC_ASSERT(sizeof(Value*) == sizeof(void*)); // NOLINT | 414 STATIC_ASSERT(sizeof(Value*) == sizeof(void*)); // NOLINT | 
| 385 struct value_type { | 415 struct value_type { | 
| 386 Key* first; | 416 Key* first; | 
| 387 Value* second; | 417 Value* second; | 
| 388 }; | 418 }; | 
| 389 | 419 | 
| 390 class Iterator { | 420 class Iterator { | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 402 : map_(map), entry_(entry) {} | 432 : map_(map), entry_(entry) {} | 
| 403 | 433 | 
| 404 const Base* map_; | 434 const Base* map_; | 
| 405 typename Base::Entry* entry_; | 435 typename Base::Entry* entry_; | 
| 406 | 436 | 
| 407 friend class TemplateHashMap; | 437 friend class TemplateHashMap; | 
| 408 }; | 438 }; | 
| 409 | 439 | 
| 410 TemplateHashMap(MatchFun match, | 440 TemplateHashMap(MatchFun match, | 
| 411 AllocationPolicy allocator = AllocationPolicy()) | 441 AllocationPolicy allocator = AllocationPolicy()) | 
| 412 : Base(Base::kDefaultHashMapCapacity, match, allocator) {} | 442 : Base(Base::kDefaultHashMapCapacity, HashKeyComp<void*, MatchFun>(match), | 
| 443 allocator) {} | |
| 413 | 444 | 
| 414 Iterator begin() const { return Iterator(this, this->Start()); } | 445 Iterator begin() const { return Iterator(this, this->Start()); } | 
| 415 Iterator end() const { return Iterator(this, nullptr); } | 446 Iterator end() const { return Iterator(this, nullptr); } | 
| 416 Iterator find(Key* key, bool insert = false, | 447 Iterator find(Key* key, bool insert = false, | 
| 417 AllocationPolicy allocator = AllocationPolicy()) { | 448 AllocationPolicy allocator = AllocationPolicy()) { | 
| 418 if (insert) { | 449 if (insert) { | 
| 419 return Iterator(this, this->LookupOrInsert(key, key->Hash(), allocator)); | 450 return Iterator(this, this->LookupOrInsert(key, key->Hash(), allocator)); | 
| 420 } | 451 } | 
| 421 return Iterator(this, this->Lookup(key, key->Hash())); | 452 return Iterator(this, this->Lookup(key, key->Hash())); | 
| 422 } | 453 } | 
| 423 }; | 454 }; | 
| 424 | 455 | 
| 425 } // namespace base | 456 } // namespace base | 
| 426 } // namespace v8 | 457 } // namespace v8 | 
| 427 | 458 | 
| 428 #endif // V8_BASE_HASHMAP_H_ | 459 #endif // V8_BASE_HASHMAP_H_ | 
| OLD | NEW |