Index: src/base/hashmap.h |
diff --git a/src/base/hashmap.h b/src/base/hashmap.h |
index 52f929db3880d15b5750c3ce4dbbaa425f92676c..7ecd68b592bfe50f6663941841bd74f707a7b473 100644 |
--- a/src/base/hashmap.h |
+++ b/src/base/hashmap.h |
@@ -24,15 +24,9 @@ class DefaultAllocationPolicy { |
V8_INLINE static void Delete(void* p) { free(p); } |
}; |
-// Metaprogramming helper to allow pointer keys to be passed by value and |
-// non-pointer keys by const reference. |
-template <typename Key> |
-struct MatchFunHelper; |
- |
-template <typename Key, typename Value, class AllocationPolicy> |
+template <typename Key, typename Value, class MatchFun, class AllocationPolicy> |
class TemplateHashMapImpl { |
public: |
- typedef typename MatchFunHelper<Key>::Fun MatchFun; |
typedef TemplateHashMapEntry<Key, Value> Entry; |
// The default capacity. This is used by the call sites which want |
@@ -42,7 +36,7 @@ class TemplateHashMapImpl { |
// initial_capacity is the size of the initial hash map; |
// it must be a power of 2 (and thus must not be 0). |
- TemplateHashMapImpl(MatchFun match, |
+ TemplateHashMapImpl(MatchFun match = MatchFun(), |
uint32_t capacity = kDefaultHashMapCapacity, |
AllocationPolicy allocator = AllocationPolicy()); |
@@ -88,20 +82,11 @@ class TemplateHashMapImpl { |
Entry* Start() const; |
Entry* Next(Entry* entry) const; |
- // Some match functions defined for convenience. |
- // TODO(leszeks): This isn't really matching pointers, so the name doesn't |
- // really make sense, but we should remove this entirely and template the map |
- // on the matching function. |
- static bool PointersMatch(typename MatchFunHelper<Key>::KeyRef key1, |
- typename MatchFunHelper<Key>::KeyRef key2) { |
- return key1 == key2; |
- } |
- |
private: |
- MatchFun match_; |
Entry* map_; |
uint32_t capacity_; |
uint32_t occupancy_; |
+ MatchFun match_; |
Entry* map_end() const { return map_ + capacity_; } |
Entry* Probe(const Key& key, uint32_t hash) const; |
@@ -111,44 +96,35 @@ class TemplateHashMapImpl { |
void Initialize(uint32_t capacity, AllocationPolicy allocator); |
void Resize(AllocationPolicy allocator); |
}; |
- |
-template <typename Key> |
-struct MatchFunHelper { |
- typedef const Key& KeyRef; |
- typedef bool (*Fun)(KeyRef key1, KeyRef key2); |
-}; |
- |
-template <typename Key> |
-struct MatchFunHelper<Key*> { |
- typedef Key* KeyRef; |
- typedef bool (*Fun)(KeyRef key1, KeyRef key2); |
-}; |
- |
-typedef TemplateHashMapImpl<void*, void*, DefaultAllocationPolicy> HashMap; |
- |
-template <typename Key, typename Value, class AllocationPolicy> |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::TemplateHashMapImpl( |
- MatchFun match, uint32_t initial_capacity, AllocationPolicy allocator) { |
- match_ = match; |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>:: |
+ TemplateHashMapImpl(MatchFun match, uint32_t initial_capacity, |
+ AllocationPolicy allocator) |
+ : match_(match) { |
Initialize(initial_capacity, allocator); |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::~TemplateHashMapImpl() { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+TemplateHashMapImpl<Key, Value, MatchFun, |
+ AllocationPolicy>::~TemplateHashMapImpl() { |
AllocationPolicy::Delete(map_); |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::Lookup(const Key& key, |
- uint32_t hash) const { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Lookup( |
+ const Key& key, uint32_t hash) const { |
Entry* entry = Probe(key, hash); |
return entry->exists() ? entry : nullptr; |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::LookupOrInsert( |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::LookupOrInsert( |
const Key& key, uint32_t hash, AllocationPolicy allocator) { |
// Find a matching entry. |
Entry* entry = Probe(key, hash); |
@@ -159,17 +135,19 @@ TemplateHashMapImpl<Key, Value, AllocationPolicy>::LookupOrInsert( |
return FillEmptyEntry(entry, key, Value(), hash, allocator); |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::InsertNew( |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::InsertNew( |
const Key& key, uint32_t hash, AllocationPolicy allocator) { |
Entry* entry = Probe(key, hash); |
return FillEmptyEntry(entry, key, Value(), hash, allocator); |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-Value TemplateHashMapImpl<Key, Value, AllocationPolicy>::Remove(const Key& key, |
- uint32_t hash) { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+Value TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Remove( |
+ const Key& key, uint32_t hash) { |
// Lookup the entry for the key to remove. |
Entry* p = Probe(key, hash); |
if (!p->exists()) { |
@@ -228,8 +206,9 @@ Value TemplateHashMapImpl<Key, Value, AllocationPolicy>::Remove(const Key& key, |
return value; |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Clear() { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Clear() { |
// Mark all entries as empty. |
const Entry* end = map_end(); |
for (Entry* entry = map_; entry < end; entry++) { |
@@ -238,15 +217,18 @@ void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Clear() { |
occupancy_ = 0; |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::Start() const { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Start() const { |
return Next(map_ - 1); |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::Next(Entry* entry) const { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Next( |
+ Entry* entry) const { |
const Entry* end = map_end(); |
DCHECK(map_ - 1 <= entry && entry < end); |
for (entry++; entry < end; entry++) { |
@@ -257,10 +239,11 @@ TemplateHashMapImpl<Key, Value, AllocationPolicy>::Next(Entry* entry) const { |
return nullptr; |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::Probe(const Key& key, |
- uint32_t hash) const { |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Probe( |
+ const Key& key, uint32_t hash) const { |
DCHECK(base::bits::IsPowerOfTwo32(capacity_)); |
Entry* entry = map_ + (hash & (capacity_ - 1)); |
const Entry* end = map_end(); |
@@ -277,9 +260,10 @@ TemplateHashMapImpl<Key, Value, AllocationPolicy>::Probe(const Key& key, |
return entry; |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-typename TemplateHashMapImpl<Key, Value, AllocationPolicy>::Entry* |
-TemplateHashMapImpl<Key, Value, AllocationPolicy>::FillEmptyEntry( |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+typename TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Entry* |
+TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::FillEmptyEntry( |
Entry* entry, const Key& key, const Value& value, uint32_t hash, |
AllocationPolicy allocator) { |
DCHECK(!entry->exists()); |
@@ -296,8 +280,9 @@ TemplateHashMapImpl<Key, Value, AllocationPolicy>::FillEmptyEntry( |
return entry; |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Initialize( |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Initialize( |
uint32_t capacity, AllocationPolicy allocator) { |
DCHECK(base::bits::IsPowerOfTwo32(capacity)); |
map_ = reinterpret_cast<Entry*>(allocator.New(capacity * sizeof(Entry))); |
@@ -309,8 +294,9 @@ void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Initialize( |
Clear(); |
} |
-template <typename Key, typename Value, class AllocationPolicy> |
-void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Resize( |
+template <typename Key, typename Value, typename MatchFun, |
+ class AllocationPolicy> |
+void TemplateHashMapImpl<Key, Value, MatchFun, AllocationPolicy>::Resize( |
AllocationPolicy allocator) { |
Entry* map = map_; |
uint32_t n = occupancy_; |
@@ -332,11 +318,35 @@ void TemplateHashMapImpl<Key, Value, AllocationPolicy>::Resize( |
AllocationPolicy::Delete(map); |
} |
+template <typename AllocationPolicy> |
+class PointerTemplateHashMapImpl |
+ : public TemplateHashMapImpl<void*, void*, bool (*)(void*, void*), |
+ AllocationPolicy> { |
+ typedef TemplateHashMapImpl<void*, void*, bool (*)(void*, void*), |
+ AllocationPolicy> |
+ Base; |
+ |
+ public: |
+ typedef bool (*MatchFun)(void*, void*); |
+ |
+ PointerTemplateHashMapImpl(MatchFun match = PointersMatch, |
+ uint32_t capacity = Base::kDefaultHashMapCapacity, |
+ AllocationPolicy allocator = AllocationPolicy()) |
+ : Base(match, capacity, allocator) {} |
+ |
+ static bool PointersMatch(void* key1, void* key2) { return key1 == key2; } |
+}; |
+ |
+typedef PointerTemplateHashMapImpl<DefaultAllocationPolicy> HashMap; |
+ |
// A hash map for pointer keys and values with an STL-like interface. |
template <class Key, class Value, class AllocationPolicy> |
-class TemplateHashMap |
- : private TemplateHashMapImpl<void*, void*, AllocationPolicy> { |
+class TemplateHashMap : private PointerTemplateHashMapImpl<AllocationPolicy> { |
+ typedef PointerTemplateHashMapImpl<AllocationPolicy> Base; |
+ |
public: |
+ typedef bool (*MatchFun)(void*, void*); |
+ |
STATIC_ASSERT(sizeof(Key*) == sizeof(void*)); // NOLINT |
STATIC_ASSERT(sizeof(Value*) == sizeof(void*)); // NOLINT |
struct value_type { |
@@ -355,25 +365,18 @@ class TemplateHashMap |
bool operator!=(const Iterator& other) { return entry_ != other.entry_; } |
private: |
- Iterator(const TemplateHashMapImpl<void*, void*, AllocationPolicy>* map, |
- typename TemplateHashMapImpl<void*, void*, |
- AllocationPolicy>::Entry* entry) |
+ Iterator(const Base* map, typename Base::Entry* entry) |
: map_(map), entry_(entry) {} |
- const TemplateHashMapImpl<void*, void*, AllocationPolicy>* map_; |
- typename TemplateHashMapImpl<void*, void*, AllocationPolicy>::Entry* entry_; |
+ const Base* map_; |
+ typename Base::Entry* entry_; |
friend class TemplateHashMap; |
}; |
- TemplateHashMap(typename TemplateHashMapImpl< |
- void*, void*, AllocationPolicy>::MatchFun match, |
+ TemplateHashMap(MatchFun match, |
AllocationPolicy allocator = AllocationPolicy()) |
- : TemplateHashMapImpl<void*, void*, AllocationPolicy>( |
- match, |
- TemplateHashMapImpl<void*, void*, |
- AllocationPolicy>::kDefaultHashMapCapacity, |
- allocator) {} |
+ : Base(match, Base::kDefaultHashMapCapacity, allocator) {} |
Iterator begin() const { return Iterator(this, this->Start()); } |
Iterator end() const { return Iterator(this, nullptr); } |