/// Allocate - Allocate space at the specified alignment. /// void *BumpPtrAllocator::Allocate(size_t Size, size_t Alignment) { if (!CurSlab) // Start a new slab if we haven't allocated one already. StartNewSlab(); // Keep track of how many bytes we've allocated. BytesAllocated += Size; // 0-byte alignment means 1-byte alignment. if (Alignment == 0) Alignment = 1; // Allocate the aligned space, going forwards from CurPtr. char *Ptr = AlignPtr(CurPtr, Alignment); // Check if we can hold it. if (Ptr + Size <= End) { CurPtr = Ptr + Size; return Ptr; } // If Size is really big, allocate a separate slab for it. size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1; if (PaddedSize > SizeThreshold) { MemSlab *NewSlab = Allocator.Allocate(PaddedSize); // Put the new slab after the current slab, since we are not allocating // into it. NewSlab->NextPtr = CurSlab->NextPtr; CurSlab->NextPtr = NewSlab; Ptr = AlignPtr((char*)(NewSlab + 1), Alignment); assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size); return Ptr; } // Otherwise, start a new slab and try again. StartNewSlab(); Ptr = AlignPtr(CurPtr, Alignment); CurPtr = Ptr + Size; assert(CurPtr <= End && "Unable to allocate memory!"); return Ptr; }
BumpPtrAllocator::BumpPtrAllocator(size_t size, size_t threshold, SlabAllocator &allocator) : SlabSize(size), SizeThreshold(threshold), Allocator(allocator), CurSlab(0), BytesAllocated(0) { StartNewSlab(); }