00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef LLVM_SUPPORT_ALLOCATOR_H
00015 #define LLVM_SUPPORT_ALLOCATOR_H
00016
00017 #include "llvm/Support/AlignOf.h"
00018 #include "llvm/Support/MathExtras.h"
00019 #include "llvm/Support/DataTypes.h"
00020 #include <algorithm>
00021 #include <cassert>
00022 #include <cstdlib>
00023 #include <cstddef>
00024
00025 namespace llvm {
00026 template <typename T> struct ReferenceAdder { typedef T& result; };
00027 template <typename T> struct ReferenceAdder<T&> { typedef T result; };
00028
00029 class MallocAllocator {
00030 public:
00031 MallocAllocator() {}
00032 ~MallocAllocator() {}
00033
00034 void Reset() {}
00035
00036 void *Allocate(size_t Size, size_t ) { return malloc(Size); }
00037
00038 template <typename T>
00039 T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); }
00040
00041 template <typename T>
00042 T *Allocate(size_t Num) {
00043 return static_cast<T*>(malloc(sizeof(T)*Num));
00044 }
00045
00046 void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); }
00047
00048 void PrintStats() const {}
00049 };
00050
00053 class MemSlab {
00054 public:
00055 size_t Size;
00056 MemSlab *NextPtr;
00057 };
00058
00064 class SlabAllocator {
00065 public:
00066 virtual ~SlabAllocator();
00067 virtual MemSlab *Allocate(size_t Size) = 0;
00068 virtual void Deallocate(MemSlab *Slab) = 0;
00069 };
00070
00074 class MallocSlabAllocator : public SlabAllocator {
00077 MallocAllocator Allocator;
00078
00079 public:
00080 MallocSlabAllocator() : Allocator() { }
00081 virtual ~MallocSlabAllocator();
00082 virtual MemSlab *Allocate(size_t Size);
00083 virtual void Deallocate(MemSlab *Slab);
00084 };
00085
00090 class BumpPtrAllocator {
00091 BumpPtrAllocator(const BumpPtrAllocator &);
00092 void operator=(const BumpPtrAllocator &);
00093
00096 size_t SlabSize;
00097
00100 size_t SizeThreshold;
00101
00105 SlabAllocator &Allocator;
00106
00109 MemSlab *CurSlab;
00110
00113 char *CurPtr;
00114
00117 char *End;
00118
00121 size_t BytesAllocated;
00122
00126 static char *AlignPtr(char *Ptr, size_t Alignment);
00127
00130 void StartNewSlab();
00131
00134 void DeallocateSlabs(MemSlab *Slab);
00135
00136 static MallocSlabAllocator DefaultSlabAllocator;
00137
00138 template<typename T> friend class SpecificBumpPtrAllocator;
00139 public:
00140 BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
00141 SlabAllocator &allocator = DefaultSlabAllocator);
00142 ~BumpPtrAllocator();
00143
00146 void Reset();
00147
00150 void *Allocate(size_t Size, size_t Alignment);
00151
00154 template <typename T>
00155 T *Allocate() {
00156 return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
00157 }
00158
00161 template <typename T>
00162 T *Allocate(size_t Num) {
00163 return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
00164 }
00165
00168 template <typename T>
00169 T *Allocate(size_t Num, size_t Alignment) {
00170
00171 size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment);
00172 return static_cast<T*>(Allocate(Num * EltSize, Alignment));
00173 }
00174
00175 void Deallocate(const void * ) {}
00176
00177 unsigned GetNumSlabs() const;
00178
00179 void PrintStats() const;
00180
00182 size_t getTotalMemory() const;
00183 };
00184
00188 template <typename T>
00189 class SpecificBumpPtrAllocator {
00190 BumpPtrAllocator Allocator;
00191 public:
00192 SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
00193 SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
00194 : Allocator(size, threshold, allocator) {}
00195
00196 ~SpecificBumpPtrAllocator() {
00197 DestroyAll();
00198 }
00199
00203 void DestroyAll() {
00204 MemSlab *Slab = Allocator.CurSlab;
00205 while (Slab) {
00206 char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
00207 (char *)Slab + Slab->Size;
00208 for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) {
00209 Ptr = Allocator.AlignPtr(Ptr, alignOf<T>());
00210 if (Ptr + sizeof(T) <= End)
00211 reinterpret_cast<T*>(Ptr)->~T();
00212 }
00213 Slab = Slab->NextPtr;
00214 }
00215 Allocator.Reset();
00216 }
00217
00219 T *Allocate(size_t num = 1) {
00220 return Allocator.Allocate<T>(num);
00221 }
00222 };
00223
00224 }
00225
00226 inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
00227 struct S {
00228 char c;
00229 union {
00230 double D;
00231 long double LD;
00232 long long L;
00233 void *P;
00234 } x;
00235 };
00236 return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
00237 offsetof(S, x)));
00238 }
00239
00240 inline void operator delete(void *, llvm::BumpPtrAllocator &) {}
00241
00242 #endif // LLVM_SUPPORT_ALLOCATOR_H