#include "llvm/Support/Allocator.h"
#include "llvm/Support/Recycler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Streams.h"
#include <ostream>
using namespace llvm;
namespace {
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);
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;
}
void *Allocate(size_t AllocSize, size_t Alignment, MemRegion **RegPtr) {
char* Result = (char*) (((uintptr_t) (NextPtr+Alignment-1))
& ~((uintptr_t) Alignment-1));
char* NextPtrTmp = Result + AllocSize;
if (unsigned (NextPtrTmp - (char*) this) <= RegionSize) {
NextPtr = NextPtrTmp;
return Result;
}
MemRegion *NewRegion = (MemRegion *)malloc(RegionSize*2);
NewRegion->Init(RegionSize*2, Alignment, this);
*RegPtr = NewRegion;
return NewRegion->Allocate(AllocSize, Alignment, RegPtr);
}
void Deallocate() {
MemRegion *next = Next;
free(this);
if (next)
next->Deallocate();
}
MemRegion *DeallocateAllButLast() {
MemRegion *next = Next;
if (!next)
return this;
free(this);
return next->DeallocateAllButLast();
}
};
}
BumpPtrAllocator::BumpPtrAllocator() {
TheMemory = malloc(4096);
((MemRegion*)TheMemory)->Init(4096, 1, 0);
}
BumpPtrAllocator::~BumpPtrAllocator() {
((MemRegion*)TheMemory)->Deallocate();
}
void BumpPtrAllocator::Reset() {
MemRegion *MRP = (MemRegion*)TheMemory;
MRP = MRP->DeallocateAllButLast();
MRP->Init(4096, 1, 0);
TheMemory = MRP;
}
void *BumpPtrAllocator::Allocate(size_t Size, size_t Align) {
MemRegion *MRP = (MemRegion*)TheMemory;
void *Ptr = MRP->Allocate(Size, Align, &MRP);
TheMemory = MRP;
return Ptr;
}
void BumpPtrAllocator::PrintStats() const {
unsigned BytesUsed = 0;
unsigned NumRegions = 0;
const MemRegion *R = (MemRegion*)TheMemory;
for (; R; R = R->getNext(), ++NumRegions)
BytesUsed += R->getNumBytesAllocated();
cerr << "\nNumber of memory regions: " << NumRegions << "\n";
cerr << "Bytes allocated: " << BytesUsed << "\n";
}
void llvm::PrintRecyclerStats(size_t Size,
size_t Align,
size_t FreeListSize) {
cerr << "Recycler element size: " << Size << '\n';
cerr << "Recycler element alignment: " << Align << '\n';
cerr << "Number of elements free for recycling: " << FreeListSize << '\n';
}