-namespace {
-/// MemRegion - This is one chunk of the BumpPtrAllocator.
-class MemRegion {
- unsigned RegionSize;
- MemRegion *Next;
- char *NextPtr;
-public:
- void Init(unsigned size, unsigned Alignment, MemRegion *next) {
- RegionSize = size;
- Next = next;
- NextPtr = (char*)(this+1);
-
- // Align NextPtr.
- NextPtr = (char*)((intptr_t)(NextPtr+Alignment-1) &
- ~(intptr_t)(Alignment-1));
- }
-
- const MemRegion *getNext() const { return Next; }
- unsigned getNumBytesAllocated() const {
- return NextPtr-(const char*)this;
+BumpPtrAllocator::BumpPtrAllocator(size_t size, size_t threshold,
+ SlabAllocator &allocator)
+ : SlabSize(size), SizeThreshold(threshold), Allocator(allocator),
+ CurSlab(0), BytesAllocated(0) { }
+
+BumpPtrAllocator::~BumpPtrAllocator() {
+ DeallocateSlabs(CurSlab);
+}
+
+/// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should
+/// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and
+/// AlignPtr(8, 4) == 8.
+char *BumpPtrAllocator::AlignPtr(char *Ptr, size_t Alignment) {
+ assert(Alignment && (Alignment & (Alignment - 1)) == 0 &&
+ "Alignment is not a power of two!");
+
+ // Do the alignment.
+ return (char*)(((uintptr_t)Ptr + Alignment - 1) &
+ ~(uintptr_t)(Alignment - 1));
+}
+
+/// StartNewSlab - Allocate a new slab and move the bump pointers over into
+/// the new slab. Modifies CurPtr and End.
+void BumpPtrAllocator::StartNewSlab() {
+ MemSlab *NewSlab = Allocator.Allocate(SlabSize);
+ NewSlab->NextPtr = CurSlab;
+ CurSlab = NewSlab;
+ CurPtr = (char*)(CurSlab + 1);
+ End = ((char*)CurSlab) + CurSlab->Size;
+}
+
+/// DeallocateSlabs - Deallocate all memory slabs after and including this
+/// one.
+void BumpPtrAllocator::DeallocateSlabs(MemSlab *Slab) {
+ while (Slab) {
+ MemSlab *NextSlab = Slab->NextPtr;
+#ifndef NDEBUG
+ // Poison the memory so stale pointers crash sooner. Note we must
+ // preserve the Size and NextPtr fields at the beginning.
+ sys::Memory::setRangeWritable(Slab + 1, Slab->Size - sizeof(MemSlab));
+ memset(Slab + 1, 0xCD, Slab->Size - sizeof(MemSlab));
+#endif
+ Allocator.Deallocate(Slab);
+ Slab = NextSlab;