//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
#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;
//===----------------------------------------------------------------------===//
/// Allocate - Allocate and return at least the specified number of bytes.
///
- void *Allocate(unsigned AllocSize, unsigned Alignment, MemRegion **RegPtr) {
- // Round size up to an even multiple of the alignment.
- AllocSize = (AllocSize+Alignment-1) & ~(Alignment-1);
+ void *Allocate(size_t AllocSize, size_t Alignment, MemRegion **RegPtr) {
- // If there is space in this region, return it.
- if (unsigned(NextPtr+AllocSize-(char*)this) <= RegionSize) {
- void *Result = NextPtr;
- NextPtr += AllocSize;
+ char* Result = (char*) (((uintptr_t) (NextPtr+Alignment-1))
+ & ~((uintptr_t) Alignment-1));
+
+ // Speculate the new value of NextPtr.
+ char* NextPtrTmp = Result + AllocSize;
+
+ // If we are still within the current region, return Result.
+ if (unsigned (NextPtrTmp - (char*) this) <= RegionSize) {
+ NextPtr = NextPtrTmp;
return Result;
}
return NewRegion->Allocate(AllocSize, Alignment, RegPtr);
}
- /// Deallocate - Release all memory for this region to the system.
- ///
+ /// Deallocate - Recursively release all memory for this and its next regions
+ /// to the system.
void Deallocate() {
MemRegion *next = Next;
free(this);
if (next)
next->Deallocate();
}
+
+ /// DeallocateAllButLast - Recursively release all memory for this and its
+ /// next regions to the system stopping at the last region in the list.
+ /// Returns the pointer to the last region.
+ MemRegion *DeallocateAllButLast() {
+ MemRegion *next = Next;
+ if (!next)
+ return this;
+ free(this);
+ return next->DeallocateAllButLast();
+ }
};
}
((MemRegion*)TheMemory)->Deallocate();
}
-void *BumpPtrAllocator::Allocate(unsigned Size, unsigned Align) {
- return ((MemRegion*)TheMemory)->Allocate(Size, Align,(MemRegion**)&TheMemory);
+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 {
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';
+}