diff options
author | Chris Lattner <sabre@nondot.org> | 2011-01-03 01:29:37 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-01-03 01:29:37 +0000 |
commit | 61a10a0dc91863b70002cc412a1277357d6a4b45 (patch) | |
tree | 5815722dc1c694d1665b9943afefa5c5c5766161 | |
parent | d957c717918c412402157b85fc51b4c6d2631381 (diff) |
Enhance ScopedHashTable to allow it to take an allocator argument.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122721 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/ADT/ScopedHashTable.h | 56 | ||||
-rw-r--r-- | include/llvm/ADT/StringMap.h | 3 | ||||
-rw-r--r-- | include/llvm/Support/Allocator.h | 2 |
3 files changed, 43 insertions, 18 deletions
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h index c96ad19707..0df2484ccc 100644 --- a/include/llvm/ADT/ScopedHashTable.h +++ b/include/llvm/ADT/ScopedHashTable.h @@ -31,12 +31,13 @@ #ifndef LLVM_ADT_SCOPEDHASHTABLE_H #define LLVM_ADT_SCOPEDHASHTABLE_H -#include <cassert> #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" namespace llvm { -template <typename K, typename V, typename KInfo = DenseMapInfo<K> > +template <typename K, typename V, typename KInfo = DenseMapInfo<K>, + typename AllocatorTy = MallocAllocator> class ScopedHashTable; template <typename K, typename V, typename KInfo = DenseMapInfo<K> > @@ -45,11 +46,8 @@ class ScopedHashTableVal { ScopedHashTableVal *NextForKey; K Key; V Val; + ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {} public: - ScopedHashTableVal(ScopedHashTableVal *nextInScope, - ScopedHashTableVal *nextForKey, const K &key, const V &val) - : NextInScope(nextInScope), NextForKey(nextForKey), Key(key), Val(val) { - } const K &getKey() const { return Key; } const V &getValue() const { return Val; } @@ -57,8 +55,27 @@ public: ScopedHashTableVal *getNextForKey() { return NextForKey; } const ScopedHashTableVal *getNextForKey() const { return NextForKey; } -public: ScopedHashTableVal *getNextInScope() { return NextInScope; } + + template <typename AllocatorTy> + static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope, + ScopedHashTableVal *nextForKey, + const K &key, const V &val, + AllocatorTy &Allocator) { + ScopedHashTableVal *New = Allocator.template Allocate<ScopedHashTableVal>(); + // Set up the value. + new (New) ScopedHashTableVal(key, val); + New->NextInScope = nextInScope; + New->NextForKey = nextForKey; + return New; + } + + template <typename AllocatorTy> + void Destroy(AllocatorTy &Allocator) { + // Free memory referenced by the item. + this->~ScopedHashTableVal(); + Allocator.Deallocate(this); + } }; template <typename K, typename V, typename KInfo = DenseMapInfo<K> > @@ -121,26 +138,35 @@ public: }; -template <typename K, typename V, typename KInfo> +template <typename K, typename V, typename KInfo, typename AllocatorTy> class ScopedHashTable { - DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo> TopLevelMap; + typedef ScopedHashTableVal<K, V, KInfo> ValTy; + DenseMap<K, ValTy*, KInfo> TopLevelMap; ScopedHashTableScope<K, V, KInfo> *CurScope; + + AllocatorTy Allocator; + ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED friend class ScopedHashTableScope<K, V, KInfo>; public: ScopedHashTable() : CurScope(0) {} + ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {} ~ScopedHashTable() { assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); } + + typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy; + typedef typename ReferenceAdder<const AllocatorTy>::result AllocatorCRefTy; + AllocatorRefTy getAllocator() { return Allocator; } + AllocatorCRefTy getAllocator() const { return Allocator; } bool count(const K &Key) const { return TopLevelMap.count(Key); } V lookup(const K &Key) { - typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator - I = TopLevelMap.find(Key); + typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key); if (I != TopLevelMap.end()) return I->second->getValue(); @@ -152,8 +178,8 @@ public: ScopedHashTableVal<K, V, KInfo> *&KeyEntry = TopLevelMap[Key]; - KeyEntry= new ScopedHashTableVal<K, V, KInfo>(CurScope->getLastValInScope(), - KeyEntry, Key, Val); + KeyEntry = ValTy::Create(CurScope->getLastValInScope(), KeyEntry, Key, Val, + Allocator); CurScope->setLastValInScope(KeyEntry); } @@ -162,7 +188,7 @@ public: iterator end() { return iterator(0); } iterator begin(const K &Key) { - typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator I = + typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key); if (I == TopLevelMap.end()) return end(); return iterator(I->second); @@ -202,7 +228,7 @@ ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() { LastValInScope = ThisEntry->getNextInScope(); // Delete this entry. - delete ThisEntry; + ThisEntry->Destroy(HT.getAllocator()); } } diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 752f55c226..bad0e6f513 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -242,9 +242,6 @@ public: }; -template <typename T> struct ReferenceAdder { typedef T& result; }; -template <typename T> struct ReferenceAdder<T&> { typedef T result; }; - /// StringMap - This is an unconventional map that is specialized for handling /// keys that are "strings", which are basically ranges of bytes. This does some /// funky memory allocation and hashing things to make it extremely efficient, diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index b080e222a1..c6807099f8 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -23,6 +23,8 @@ #include <cstddef> namespace llvm { +template <typename T> struct ReferenceAdder { typedef T& result; }; +template <typename T> struct ReferenceAdder<T&> { typedef T result; }; class MallocAllocator { public: |