[Allocator] Hoist the external helper function into a namespace scope
[oota-llvm.git] / include / llvm / Support / Allocator.h
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/ADT/SmallVector.h"
18 #include "llvm/Support/AlignOf.h"
19 #include "llvm/Support/DataTypes.h"
20 #include "llvm/Support/MathExtras.h"
21 #include "llvm/Support/Memory.h"
22 #include <algorithm>
23 #include <cassert>
24 #include <cstddef>
25 #include <cstdlib>
26
27 namespace llvm {
28 template <typename T> struct ReferenceAdder {
29   typedef T &result;
30 };
31 template <typename T> struct ReferenceAdder<T &> {
32   typedef T result;
33 };
34
35 class MallocAllocator {
36 public:
37   MallocAllocator() {}
38   ~MallocAllocator() {}
39
40   void Reset() {}
41
42   void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
43
44   template <typename T> T *Allocate() {
45     return static_cast<T *>(malloc(sizeof(T)));
46   }
47
48   template <typename T> T *Allocate(size_t Num) {
49     return static_cast<T *>(malloc(sizeof(T) * Num));
50   }
51
52   void Deallocate(const void *Ptr) { free(const_cast<void *>(Ptr)); }
53
54   void PrintStats() const {}
55 };
56
57 /// MallocSlabAllocator - The default slab allocator for the bump allocator
58 /// is an adapter class for MallocAllocator that just forwards the method
59 /// calls and translates the arguments.
60 class MallocSlabAllocator {
61   /// Allocator - The underlying allocator that we forward to.
62   ///
63   MallocAllocator Allocator;
64
65 public:
66   void *Allocate(size_t Size) { return Allocator.Allocate(Size, 0); }
67   void Deallocate(void *Slab, size_t Size) { Allocator.Deallocate(Slab); }
68 };
69
70 namespace detail {
71
72 // We call out to an external function to actually print the message as the
73 // printing code uses Allocator.h in its implementation.
74 void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated,
75                                 size_t TotalMemory);
76 } // End namespace detail.
77
78 /// \brief Allocate memory in an ever growing pool, as if by bump-pointer.
79 ///
80 /// This isn't strictly a bump-pointer allocator as it uses backing slabs of
81 /// memory rather than relying on boundless contiguous heap. However, it has
82 /// bump-pointer semantics in that is a monotonically growing pool of memory
83 /// where every allocation is found by merely allocating the next N bytes in
84 /// the slab, or the next N bytes in the next slab.
85 ///
86 /// Note that this also has a threshold for forcing allocations above a certain
87 /// size into their own slab.
88 ///
89 /// The BumpPtrAllocatorImpl template defaults to using a MallocSlabAllocator
90 /// object, which wraps malloc, to allocate memory, but it can be changed to
91 /// use a custom allocator.
92 template <typename AllocatorT = MallocSlabAllocator, size_t SlabSize = 4096,
93           size_t SizeThreshold = SlabSize>
94 class BumpPtrAllocatorImpl {
95   BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
96   void operator=(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
97
98 public:
99   static_assert(SizeThreshold <= SlabSize,
100                 "The SizeThreshold must be at most the SlabSize to ensure "
101                 "that objects larger than a slab go into their own memory "
102                 "allocation.");
103
104   BumpPtrAllocatorImpl()
105       : CurPtr(nullptr), End(nullptr), BytesAllocated(0), Allocator() {}
106   template <typename T>
107   BumpPtrAllocatorImpl(T &&Allocator)
108       : CurPtr(nullptr), End(nullptr), BytesAllocated(0),
109         Allocator(std::forward<T &&>(Allocator)) {}
110   ~BumpPtrAllocatorImpl() {
111     DeallocateSlabs(Slabs.begin(), Slabs.end());
112     DeallocateCustomSizedSlabs();
113   }
114
115   /// \brief Deallocate all but the current slab and reset the current pointer
116   /// to the beginning of it, freeing all memory allocated so far.
117   void Reset() {
118     if (Slabs.empty())
119       return;
120
121     // Reset the state.
122     BytesAllocated = 0;
123     CurPtr = (char *)Slabs.front();
124     End = CurPtr + SlabSize;
125
126     // Deallocate all but the first slab, and all custome sized slabs.
127     DeallocateSlabs(std::next(Slabs.begin()), Slabs.end());
128     Slabs.erase(std::next(Slabs.begin()), Slabs.end());
129     DeallocateCustomSizedSlabs();
130     CustomSizedSlabs.clear();
131   }
132
133   /// \brief Allocate space at the specified alignment.
134   void *Allocate(size_t Size, size_t Alignment) {
135     if (!CurPtr) // Start a new slab if we haven't allocated one already.
136       StartNewSlab();
137
138     // Keep track of how many bytes we've allocated.
139     BytesAllocated += Size;
140
141     // 0-byte alignment means 1-byte alignment.
142     if (Alignment == 0)
143       Alignment = 1;
144
145     // Allocate the aligned space, going forwards from CurPtr.
146     char *Ptr = alignPtr(CurPtr, Alignment);
147
148     // Check if we can hold it.
149     if (Ptr + Size <= End) {
150       CurPtr = Ptr + Size;
151       // Update the allocation point of this memory block in MemorySanitizer.
152       // Without this, MemorySanitizer messages for values originated from here
153       // will point to the allocation of the entire slab.
154       __msan_allocated_memory(Ptr, Size);
155       return Ptr;
156     }
157
158     // If Size is really big, allocate a separate slab for it.
159     size_t PaddedSize = Size + Alignment - 1;
160     if (PaddedSize > SizeThreshold) {
161       void *NewSlab = Allocator.Allocate(PaddedSize);
162       CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize));
163
164       Ptr = alignPtr((char *)NewSlab, Alignment);
165       assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + PaddedSize);
166       __msan_allocated_memory(Ptr, Size);
167       return Ptr;
168     }
169
170     // Otherwise, start a new slab and try again.
171     StartNewSlab();
172     Ptr = alignPtr(CurPtr, Alignment);
173     CurPtr = Ptr + Size;
174     assert(CurPtr <= End && "Unable to allocate memory!");
175     __msan_allocated_memory(Ptr, Size);
176     return Ptr;
177   }
178
179   /// \brief Allocate space for one object without constructing it.
180   template <typename T> T *Allocate() {
181     return static_cast<T *>(Allocate(sizeof(T), AlignOf<T>::Alignment));
182   }
183
184   /// \brief Allocate space for an array of objects without constructing them.
185   template <typename T> T *Allocate(size_t Num) {
186     return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
187   }
188
189   /// \brief Allocate space for an array of objects with the specified alignment
190   /// and without constructing them.
191   template <typename T> T *Allocate(size_t Num, size_t Alignment) {
192     // Round EltSize up to the specified alignment.
193     size_t EltSize = (sizeof(T) + Alignment - 1) & (-Alignment);
194     return static_cast<T *>(Allocate(Num * EltSize, Alignment));
195   }
196
197   void Deallocate(const void * /*Ptr*/) {}
198
199   size_t GetNumSlabs() const { return Slabs.size() + CustomSizedSlabs.size(); }
200
201   size_t getTotalMemory() const {
202     size_t TotalMemory = 0;
203     for (auto I = Slabs.begin(), E = Slabs.end(); I != E; ++I)
204       TotalMemory += computeSlabSize(std::distance(Slabs.begin(), I));
205     for (auto &PtrAndSize : CustomSizedSlabs)
206       TotalMemory += PtrAndSize.second;
207     return TotalMemory;
208   }
209
210   void PrintStats() const {
211     detail::printBumpPtrAllocatorStats(Slabs.size(), BytesAllocated,
212                                        getTotalMemory());
213   }
214
215 private:
216   /// \brief The current pointer into the current slab.
217   ///
218   /// This points to the next free byte in the slab.
219   char *CurPtr;
220
221   /// \brief The end of the current slab.
222   char *End;
223
224   /// \brief The slabs allocated so far.
225   SmallVector<void *, 4> Slabs;
226
227   /// \brief Custom-sized slabs allocated for too-large allocation requests.
228   SmallVector<std::pair<void *, size_t>, 0> CustomSizedSlabs;
229
230   /// \brief How many bytes we've allocated.
231   ///
232   /// Used so that we can compute how much space was wasted.
233   size_t BytesAllocated;
234
235   /// \brief The allocator instance we use to get slabs of memory.
236   AllocatorT Allocator;
237
238   static size_t computeSlabSize(unsigned SlabIdx) {
239     // Scale the actual allocated slab size based on the number of slabs
240     // allocated. Every 128 slabs allocated, we double the allocated size to
241     // reduce allocation frequency, but saturate at multiplying the slab size by
242     // 2^30.
243     return SlabSize * ((size_t)1 << std::min<size_t>(30, SlabIdx / 128));
244   }
245
246   /// \brief Allocate a new slab and move the bump pointers over into the new
247   /// slab, modifying CurPtr and End.
248   void StartNewSlab() {
249     size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
250
251     void *NewSlab = Allocator.Allocate(AllocatedSlabSize);
252     Slabs.push_back(NewSlab);
253     CurPtr = (char *)(NewSlab);
254     End = ((char *)NewSlab) + AllocatedSlabSize;
255   }
256
257   /// \brief Deallocate a sequence of slabs.
258   void DeallocateSlabs(SmallVectorImpl<void *>::iterator I,
259                        SmallVectorImpl<void *>::iterator E) {
260     for (; I != E; ++I) {
261       size_t AllocatedSlabSize =
262           computeSlabSize(std::distance(Slabs.begin(), I));
263 #ifndef NDEBUG
264       // Poison the memory so stale pointers crash sooner.  Note we must
265       // preserve the Size and NextPtr fields at the beginning.
266       sys::Memory::setRangeWritable(*I, AllocatedSlabSize);
267       memset(*I, 0xCD, AllocatedSlabSize);
268 #endif
269       Allocator.Deallocate(*I, AllocatedSlabSize);
270     }
271   }
272
273   /// \brief Deallocate all memory for custom sized slabs.
274   void DeallocateCustomSizedSlabs() {
275     for (auto &PtrAndSize : CustomSizedSlabs) {
276       void *Ptr = PtrAndSize.first;
277       size_t Size = PtrAndSize.second;
278 #ifndef NDEBUG
279       // Poison the memory so stale pointers crash sooner.  Note we must
280       // preserve the Size and NextPtr fields at the beginning.
281       sys::Memory::setRangeWritable(Ptr, Size);
282       memset(Ptr, 0xCD, Size);
283 #endif
284       Allocator.Deallocate(Ptr, Size);
285     }
286   }
287
288   template <typename T> friend class SpecificBumpPtrAllocator;
289 };
290
291 /// \brief The standard BumpPtrAllocator which just uses the default template
292 /// paramaters.
293 typedef BumpPtrAllocatorImpl<> BumpPtrAllocator;
294
295 /// \brief A BumpPtrAllocator that allows only elements of a specific type to be
296 /// allocated.
297 ///
298 /// This allows calling the destructor in DestroyAll() and when the allocator is
299 /// destroyed.
300 template <typename T> class SpecificBumpPtrAllocator {
301   BumpPtrAllocator Allocator;
302
303 public:
304   SpecificBumpPtrAllocator() : Allocator() {}
305
306   ~SpecificBumpPtrAllocator() { DestroyAll(); }
307
308   /// Call the destructor of each allocated object and deallocate all but the
309   /// current slab and reset the current pointer to the beginning of it, freeing
310   /// all memory allocated so far.
311   void DestroyAll() {
312     auto DestroyElements = [](char *Begin, char *End) {
313       assert(Begin == alignPtr(Begin, alignOf<T>()));
314       for (char *Ptr = Begin; Ptr + sizeof(T) <= End; Ptr += sizeof(T))
315         reinterpret_cast<T *>(Ptr)->~T();
316     };
317
318     for (auto I = Allocator.Slabs.begin(), E = Allocator.Slabs.end(); I != E;
319          ++I) {
320       size_t AllocatedSlabSize = BumpPtrAllocator::computeSlabSize(
321           std::distance(Allocator.Slabs.begin(), I));
322       char *Begin = alignPtr((char *)*I, alignOf<T>());
323       char *End = *I == Allocator.Slabs.back() ? Allocator.CurPtr
324                                                : (char *)*I + AllocatedSlabSize;
325
326       DestroyElements(Begin, End);
327     }
328
329     for (auto &PtrAndSize : Allocator.CustomSizedSlabs) {
330       void *Ptr = PtrAndSize.first;
331       size_t Size = PtrAndSize.second;
332       DestroyElements(alignPtr((char *)Ptr, alignOf<T>()), (char *)Ptr + Size);
333     }
334
335     Allocator.Reset();
336   }
337
338   /// \brief Allocate space for an array of objects without constructing them.
339   T *Allocate(size_t num = 1) { return Allocator.Allocate<T>(num); }
340
341 private:
342 };
343
344 }  // end namespace llvm
345
346 template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
347 void *operator new(size_t Size,
348                    llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize,
349                                               SizeThreshold> &Allocator) {
350   struct S {
351     char c;
352     union {
353       double D;
354       long double LD;
355       long long L;
356       void *P;
357     } x;
358   };
359   return Allocator.Allocate(
360       Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
361 }
362
363 template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
364 void operator delete(
365     void *, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold> &) {
366 }
367
368 #endif // LLVM_SUPPORT_ALLOCATOR_H