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