summaryrefslogtreecommitdiffstats
path: root/include/llvm/Support/Allocator.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support/Allocator.h')
-rw-r--r--include/llvm/Support/Allocator.h40
1 files changed, 40 insertions, 0 deletions
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index b1f59dc..bd38180 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -133,6 +133,7 @@ class BumpPtrAllocator {
static MallocSlabAllocator DefaultSlabAllocator;
+ template<typename T> friend class SpecificBumpPtrAllocator;
public:
BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
SlabAllocator &allocator = DefaultSlabAllocator);
@@ -176,6 +177,45 @@ public:
void PrintStats() const;
};
+/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only
+/// elements of one type to be allocated. This allows calling the destructor
+/// in DestroyAll() and when the allocator is destroyed.
+template <typename T>
+class SpecificBumpPtrAllocator {
+ BumpPtrAllocator Allocator;
+public:
+ SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
+ SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
+ : Allocator(size, threshold, allocator) {}
+
+ ~SpecificBumpPtrAllocator() {
+ DestroyAll();
+ }
+
+ /// Call the destructor of each allocated object and deallocate all but the
+ /// current slab and reset the current pointer to the beginning of it, freeing
+ /// all memory allocated so far.
+ void DestroyAll() {
+ MemSlab *Slab = Allocator.CurSlab;
+ while (Slab) {
+ char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
+ (char *)Slab + Slab->Size;
+ for (char *Ptr = (char*)Slab+1; Ptr < End; Ptr += sizeof(T)) {
+ Ptr = Allocator.AlignPtr(Ptr, alignof<T>());
+ if (Ptr + sizeof(T) <= End)
+ reinterpret_cast<T*>(Ptr)->~T();
+ }
+ Slab = Slab->NextPtr;
+ }
+ Allocator.Reset();
+ }
+
+ /// Allocate space for a specific count of elements.
+ T *Allocate(size_t num = 1) {
+ return Allocator.Allocate<T>(num);
+ }
+};
+
} // end namespace llvm
inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
OpenPOWER on IntegriCloud