19f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===// 29f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// 39f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// The LLVM Compiler Infrastructure 49f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 79f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// 89f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner//===----------------------------------------------------------------------===// 99f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// 109f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// This file defines the MallocAllocator and BumpPtrAllocator interfaces. 119f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner// 129f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner//===----------------------------------------------------------------------===// 139f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner 149f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner#ifndef LLVM_SUPPORT_ALLOCATOR_H 159f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner#define LLVM_SUPPORT_ALLOCATOR_H 169f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner 17869a3344f17975f57a328dcc8bacf6775344c045Ted Kremenek#include "llvm/Support/AlignOf.h" 189553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman#include "llvm/Support/MathExtras.h" 191f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h" 209553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman#include <algorithm> 218f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner#include <cassert> 229f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner#include <cstdlib> 239553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman#include <cstddef> 249f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner 259f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattnernamespace llvm { 2661a10a0dc91863b70002cc412a1277357d6a4b45Chris Lattnertemplate <typename T> struct ReferenceAdder { typedef T& result; }; 2761a10a0dc91863b70002cc412a1277357d6a4b45Chris Lattnertemplate <typename T> struct ReferenceAdder<T&> { typedef T result; }; 28fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 299f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattnerclass MallocAllocator { 309f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattnerpublic: 319f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner MallocAllocator() {} 329f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner ~MallocAllocator() {} 33fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 34188b5224fd9c8573713665c77f9d2f415bcc4ff1Evan Cheng void Reset() {} 35f4dc289cea5dbfa272b54a8436a6bda6b226cee2Dan Gohman 368032020cf209721bc104648f28b1c4b45fb88691Bill Wendling void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); } 37fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 38869a3344f17975f57a328dcc8bacf6775344c045Ted Kremenek template <typename T> 39f4dc289cea5dbfa272b54a8436a6bda6b226cee2Dan Gohman T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); } 40fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 4107c2a78c2b9bf2500ece856c2df2dc043db9acb6Ted Kremenek template <typename T> 42fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman T *Allocate(size_t Num) { 4307c2a78c2b9bf2500ece856c2df2dc043db9acb6Ted Kremenek return static_cast<T*>(malloc(sizeof(T)*Num)); 4407c2a78c2b9bf2500ece856c2df2dc043db9acb6Ted Kremenek } 45fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 463f4c81de0ac7ff75e538dd68ef4ecfa204760bc9Ted Kremenek void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); } 47f4dc289cea5dbfa272b54a8436a6bda6b226cee2Dan Gohman 489f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner void PrintStats() const {} 499f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner}; 509f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner 518f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// MemSlab - This structure lives at the beginning of every slab allocated by 528f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// the bump allocator. 538f51a62b41a425f7fe262ff20cee835129ecc072Reid Klecknerclass MemSlab { 548f51a62b41a425f7fe262ff20cee835129ecc072Reid Klecknerpublic: 558f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner size_t Size; 568f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner MemSlab *NextPtr; 578f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner}; 588f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 598f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// SlabAllocator - This class can be used to parameterize the underlying 608f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// allocation strategy for the bump allocator. In particular, this is used 618f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// by the JIT to allocate contiguous swathes of executable memory. The 628f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// interface uses MemSlab's instead of void *'s so that the allocator 638f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// doesn't have to remember the size of the pointer it allocated. 648f51a62b41a425f7fe262ff20cee835129ecc072Reid Klecknerclass SlabAllocator { 658f51a62b41a425f7fe262ff20cee835129ecc072Reid Klecknerpublic: 668f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner virtual ~SlabAllocator(); 678f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner virtual MemSlab *Allocate(size_t Size) = 0; 688f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner virtual void Deallocate(MemSlab *Slab) = 0; 698f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner}; 708f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 718f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// MallocSlabAllocator - The default slab allocator for the bump allocator 728f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// is an adapter class for MallocAllocator that just forwards the method 738f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// calls and translates the arguments. 748f51a62b41a425f7fe262ff20cee835129ecc072Reid Klecknerclass MallocSlabAllocator : public SlabAllocator { 758f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// Allocator - The underlying allocator that we forward to. 768f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// 778f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner MallocAllocator Allocator; 788f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 798f51a62b41a425f7fe262ff20cee835129ecc072Reid Klecknerpublic: 808f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner MallocSlabAllocator() : Allocator() { } 818f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner virtual ~MallocSlabAllocator(); 828f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner virtual MemSlab *Allocate(size_t Size); 838f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner virtual void Deallocate(MemSlab *Slab); 848f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner}; 858f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 868f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// BumpPtrAllocator - This allocator is useful for containers that need 878f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner/// very simple memory allocation strategies. In particular, this just keeps 889f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner/// allocating memory, and never deletes it until the entire block is dead. This 899f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner/// makes allocation speedy, but must only be used when the trade-off is ok. 909f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattnerclass BumpPtrAllocator { 917698252750b29bbd8de20f5404241953221470f4Dan Gohman BumpPtrAllocator(const BumpPtrAllocator &); // do not implement 927698252750b29bbd8de20f5404241953221470f4Dan Gohman void operator=(const BumpPtrAllocator &); // do not implement 937698252750b29bbd8de20f5404241953221470f4Dan Gohman 948f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// SlabSize - Allocate data into slabs of this size unless we get an 958f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// allocation above SizeThreshold. 968f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner size_t SlabSize; 978f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 988f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// SizeThreshold - For any allocation larger than this threshold, we should 998f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// allocate a separate slab. 1008f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner size_t SizeThreshold; 1018f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1028f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// Allocator - The underlying allocator we use to get slabs of memory. This 1038f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// defaults to MallocSlabAllocator, which wraps malloc, but it could be 1048f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// changed to use a custom allocator. 1058f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner SlabAllocator &Allocator; 1068f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1078f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// CurSlab - The slab that we are currently allocating into. 1088f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// 1098f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner MemSlab *CurSlab; 1108f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1118f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// CurPtr - The current pointer into the current slab. This points to the 1128f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// next free byte in the slab. 1138f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner char *CurPtr; 1148f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1158f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// End - The end of the current slab. 1168f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// 1178f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner char *End; 1188f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1198f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// BytesAllocated - This field tracks how many bytes we've allocated, so 1208f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// that we can compute how much space was wasted. 1218f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner size_t BytesAllocated; 1228f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1238f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should 1248f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and 1258f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// AlignPtr(8, 4) == 8. 1268f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner static char *AlignPtr(char *Ptr, size_t Alignment); 1278f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1288f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// StartNewSlab - Allocate a new slab and move the bump pointers over into 1298f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// the new slab. Modifies CurPtr and End. 1308f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner void StartNewSlab(); 1318f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1328f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// DeallocateSlabs - Deallocate all memory slabs after and including this 1338f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// one. 1348f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner void DeallocateSlabs(MemSlab *Slab); 1358f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 136c5b7b196770f8c3c83e4ec06c0f2a1f53b623b6fBill Wendling static MallocSlabAllocator DefaultSlabAllocator; 1378f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 138991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer template<typename T> friend class SpecificBumpPtrAllocator; 1399f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattnerpublic: 1408f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096, 141c5b7b196770f8c3c83e4ec06c0f2a1f53b623b6fBill Wendling SlabAllocator &allocator = DefaultSlabAllocator); 1429f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner ~BumpPtrAllocator(); 143fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 1448f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// Reset - Deallocate all but the current slab and reset the current pointer 1458f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// to the beginning of it, freeing all memory allocated so far. 146188b5224fd9c8573713665c77f9d2f415bcc4ff1Evan Cheng void Reset(); 147f4dc289cea5dbfa272b54a8436a6bda6b226cee2Dan Gohman 1488f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// Allocate - Allocate space at the specified alignment. 1498f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner /// 15034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng void *Allocate(size_t Size, size_t Alignment); 151869a3344f17975f57a328dcc8bacf6775344c045Ted Kremenek 152603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner /// Allocate space, but do not construct, one object. 153603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner /// 154869a3344f17975f57a328dcc8bacf6775344c045Ted Kremenek template <typename T> 155fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman T *Allocate() { 156f4dc289cea5dbfa272b54a8436a6bda6b226cee2Dan Gohman return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment)); 157869a3344f17975f57a328dcc8bacf6775344c045Ted Kremenek } 158fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 159603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner /// Allocate space for an array of objects. This does not construct the 160603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner /// objects though. 161e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman template <typename T> 162fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman T *Allocate(size_t Num) { 163e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment)); 164e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman } 165fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman 166603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner /// Allocate space for a specific count of elements and with a specified 167603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner /// alignment. 168603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner template <typename T> 169535f390bc30973fdcf29f616896bd96dd49e1737Mon P Wang T *Allocate(size_t Num, size_t Alignment) { 170603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner // Round EltSize up to the specified alignment. 171535f390bc30973fdcf29f616896bd96dd49e1737Mon P Wang size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment); 172603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner return static_cast<T*>(Allocate(Num * EltSize, Alignment)); 173603884021010e227db6cc3fcc4c7f5e555e4a8dcChris Lattner } 1743f4c81de0ac7ff75e538dd68ef4ecfa204760bc9Ted Kremenek 1753f4c81de0ac7ff75e538dd68ef4ecfa204760bc9Ted Kremenek void Deallocate(const void * /*Ptr*/) {} 176f4dc289cea5dbfa272b54a8436a6bda6b226cee2Dan Gohman 1778f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner unsigned GetNumSlabs() const; 1788f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner 1799f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner void PrintStats() const; 1801da29dd3f85f5e3f50365d8e75efb8cbfba84381Ted Kremenek 1811da29dd3f85f5e3f50365d8e75efb8cbfba84381Ted Kremenek /// Compute the total physical memory allocated by this allocator. 1821da29dd3f85f5e3f50365d8e75efb8cbfba84381Ted Kremenek size_t getTotalMemory() const; 1839f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner}; 1849f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner 185991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only 186991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer/// elements of one type to be allocated. This allows calling the destructor 187991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer/// in DestroyAll() and when the allocator is destroyed. 188991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramertemplate <typename T> 189991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramerclass SpecificBumpPtrAllocator { 190991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer BumpPtrAllocator Allocator; 191991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramerpublic: 192991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096, 193991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator) 194991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer : Allocator(size, threshold, allocator) {} 195991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer 196991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer ~SpecificBumpPtrAllocator() { 197991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer DestroyAll(); 198991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer } 199991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer 200991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer /// Call the destructor of each allocated object and deallocate all but the 201991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer /// current slab and reset the current pointer to the beginning of it, freeing 202991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer /// all memory allocated so far. 203991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer void DestroyAll() { 204991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer MemSlab *Slab = Allocator.CurSlab; 205991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer while (Slab) { 206991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr : 207991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer (char *)Slab + Slab->Size; 20886bfd34ece523d863282ef2a2e4cf451c387c559Torok Edwin for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) { 20916c3b647eb100fe404ee65f106d563ddef6c74b7Chris Lattner Ptr = Allocator.AlignPtr(Ptr, alignOf<T>()); 210bbef815a3beeba3161cdad8e1cc108644bfc5ddcJakob Stoklund Olesen if (Ptr + sizeof(T) <= End) 211991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer reinterpret_cast<T*>(Ptr)->~T(); 212991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer } 213991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer Slab = Slab->NextPtr; 214991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer } 215991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer Allocator.Reset(); 216991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer } 217991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer 218991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer /// Allocate space for a specific count of elements. 219991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer T *Allocate(size_t num = 1) { 220991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer return Allocator.Allocate<T>(num); 221991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer } 222991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer}; 223991de14dd62dcbab4b31357ae22dc5b053ba50a0Benjamin Kramer 224abb8bf131c8542ff25964b69797558d425ed93c8Dan Gohman} // end namespace llvm 2259f617d64c5f3f2a0949f359f63b1cb3bff4b3a9bChris Lattner 2269553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohmaninline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) { 2279553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman struct S { 2289553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman char c; 2299553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman union { 2309553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman double D; 2319553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman long double LD; 2329553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman long long L; 2339553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman void *P; 2349553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman } x; 2359553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman }; 236aea1b501ceff5a10e9def91febcc80926196391dDan Gohman return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size), 237debbef20ee27e7808a81f261fd9da6c87c6179f0Dan Gohman offsetof(S, x))); 2389553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman} 2399553188fccbf0ae9c5b6bef26d0d2bd5feff8b59Dan Gohman 240180c3d4edd1219832be8f2cf91f5f73f9757c36fBenjamin Kramerinline void operator delete(void *, llvm::BumpPtrAllocator &) {} 241180c3d4edd1219832be8f2cf91f5f73f9757c36fBenjamin Kramer 2428f51a62b41a425f7fe262ff20cee835129ecc072Reid Kleckner#endif // LLVM_SUPPORT_ALLOCATOR_H 243