Allocator.h revision 198892
1//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the MallocAllocator and BumpPtrAllocator interfaces. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SUPPORT_ALLOCATOR_H 15#define LLVM_SUPPORT_ALLOCATOR_H 16 17#include "llvm/Support/AlignOf.h" 18#include "llvm/System/DataTypes.h" 19#include <cassert> 20#include <cstdlib> 21 22namespace llvm { 23 24class MallocAllocator { 25public: 26 MallocAllocator() {} 27 ~MallocAllocator() {} 28 29 void Reset() {} 30 31 void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); } 32 33 template <typename T> 34 T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); } 35 36 template <typename T> 37 T *Allocate(size_t Num) { 38 return static_cast<T*>(malloc(sizeof(T)*Num)); 39 } 40 41 void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); } 42 43 void PrintStats() const {} 44}; 45 46/// MemSlab - This structure lives at the beginning of every slab allocated by 47/// the bump allocator. 48class MemSlab { 49public: 50 size_t Size; 51 MemSlab *NextPtr; 52}; 53 54/// SlabAllocator - This class can be used to parameterize the underlying 55/// allocation strategy for the bump allocator. In particular, this is used 56/// by the JIT to allocate contiguous swathes of executable memory. The 57/// interface uses MemSlab's instead of void *'s so that the allocator 58/// doesn't have to remember the size of the pointer it allocated. 59class SlabAllocator { 60public: 61 virtual ~SlabAllocator(); 62 virtual MemSlab *Allocate(size_t Size) = 0; 63 virtual void Deallocate(MemSlab *Slab) = 0; 64}; 65 66/// MallocSlabAllocator - The default slab allocator for the bump allocator 67/// is an adapter class for MallocAllocator that just forwards the method 68/// calls and translates the arguments. 69class MallocSlabAllocator : public SlabAllocator { 70 /// Allocator - The underlying allocator that we forward to. 71 /// 72 MallocAllocator Allocator; 73 74public: 75 MallocSlabAllocator() : Allocator() { } 76 virtual ~MallocSlabAllocator(); 77 virtual MemSlab *Allocate(size_t Size); 78 virtual void Deallocate(MemSlab *Slab); 79}; 80 81/// BumpPtrAllocator - This allocator is useful for containers that need 82/// very simple memory allocation strategies. In particular, this just keeps 83/// allocating memory, and never deletes it until the entire block is dead. This 84/// makes allocation speedy, but must only be used when the trade-off is ok. 85class BumpPtrAllocator { 86 BumpPtrAllocator(const BumpPtrAllocator &); // do not implement 87 void operator=(const BumpPtrAllocator &); // do not implement 88 89 /// SlabSize - Allocate data into slabs of this size unless we get an 90 /// allocation above SizeThreshold. 91 size_t SlabSize; 92 93 /// SizeThreshold - For any allocation larger than this threshold, we should 94 /// allocate a separate slab. 95 size_t SizeThreshold; 96 97 /// Allocator - The underlying allocator we use to get slabs of memory. This 98 /// defaults to MallocSlabAllocator, which wraps malloc, but it could be 99 /// changed to use a custom allocator. 100 SlabAllocator &Allocator; 101 102 /// CurSlab - The slab that we are currently allocating into. 103 /// 104 MemSlab *CurSlab; 105 106 /// CurPtr - The current pointer into the current slab. This points to the 107 /// next free byte in the slab. 108 char *CurPtr; 109 110 /// End - The end of the current slab. 111 /// 112 char *End; 113 114 /// BytesAllocated - This field tracks how many bytes we've allocated, so 115 /// that we can compute how much space was wasted. 116 size_t BytesAllocated; 117 118 /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should 119 /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and 120 /// AlignPtr(8, 4) == 8. 121 static char *AlignPtr(char *Ptr, size_t Alignment); 122 123 /// StartNewSlab - Allocate a new slab and move the bump pointers over into 124 /// the new slab. Modifies CurPtr and End. 125 void StartNewSlab(); 126 127 /// DeallocateSlabs - Deallocate all memory slabs after and including this 128 /// one. 129 void DeallocateSlabs(MemSlab *Slab); 130 131 static MallocSlabAllocator DefaultSlabAllocator; 132 133public: 134 BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096, 135 SlabAllocator &allocator = DefaultSlabAllocator); 136 ~BumpPtrAllocator(); 137 138 /// Reset - Deallocate all but the current slab and reset the current pointer 139 /// to the beginning of it, freeing all memory allocated so far. 140 void Reset(); 141 142 /// Allocate - Allocate space at the specified alignment. 143 /// 144 void *Allocate(size_t Size, size_t Alignment); 145 146 /// Allocate space, but do not construct, one object. 147 /// 148 template <typename T> 149 T *Allocate() { 150 return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment)); 151 } 152 153 /// Allocate space for an array of objects. This does not construct the 154 /// objects though. 155 template <typename T> 156 T *Allocate(size_t Num) { 157 return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment)); 158 } 159 160 /// Allocate space for a specific count of elements and with a specified 161 /// alignment. 162 template <typename T> 163 T *Allocate(size_t Num, size_t Alignment) { 164 // Round EltSize up to the specified alignment. 165 size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment); 166 return static_cast<T*>(Allocate(Num * EltSize, Alignment)); 167 } 168 169 void Deallocate(const void * /*Ptr*/) {} 170 171 unsigned GetNumSlabs() const; 172 173 void PrintStats() const; 174}; 175 176} // end namespace llvm 177 178#endif // LLVM_SUPPORT_ALLOCATOR_H 179