1 //===--- Allocator.cpp - Simple memory allocation abstraction -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the BumpPtrAllocator interface.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Support/Allocator.h"
15 #include "llvm/Support/Recycler.h"
16 #include "llvm/Support/DataTypes.h"
17 #include "llvm/Support/Streams.h"
21 //===----------------------------------------------------------------------===//
22 // MemRegion class implementation
23 //===----------------------------------------------------------------------===//
26 /// MemRegion - This is one chunk of the BumpPtrAllocator.
32 void Init(unsigned size
, unsigned Alignment
, MemRegion
*next
) {
35 NextPtr
= (char*)(this+1);
38 NextPtr
= (char*)((intptr_t)(NextPtr
+Alignment
-1) &
39 ~(intptr_t)(Alignment
-1));
42 const MemRegion
*getNext() const { return Next
; }
43 unsigned getNumBytesAllocated() const {
44 return NextPtr
-(const char*)this;
47 /// Allocate - Allocate and return at least the specified number of bytes.
49 void *Allocate(size_t AllocSize
, size_t Alignment
, MemRegion
**RegPtr
) {
51 char* Result
= (char*) (((uintptr_t) (NextPtr
+Alignment
-1))
52 & ~((uintptr_t) Alignment
-1));
54 // Speculate the new value of NextPtr.
55 char* NextPtrTmp
= Result
+ AllocSize
;
57 // If we are still within the current region, return Result.
58 if (unsigned (NextPtrTmp
- (char*) this) <= RegionSize
) {
63 // Otherwise, we have to allocate a new chunk. Create one twice as big as
65 MemRegion
*NewRegion
= (MemRegion
*)malloc(RegionSize
*2);
66 NewRegion
->Init(RegionSize
*2, Alignment
, this);
68 // Update the current "first region" pointer to point to the new region.
71 // Try allocating from it now.
72 return NewRegion
->Allocate(AllocSize
, Alignment
, RegPtr
);
75 /// Deallocate - Recursively release all memory for this and its next regions
78 MemRegion
*next
= Next
;
84 /// DeallocateAllButLast - Recursively release all memory for this and its
85 /// next regions to the system stopping at the last region in the list.
86 /// Returns the pointer to the last region.
87 MemRegion
*DeallocateAllButLast() {
88 MemRegion
*next
= Next
;
92 return next
->DeallocateAllButLast();
97 //===----------------------------------------------------------------------===//
98 // BumpPtrAllocator class implementation
99 //===----------------------------------------------------------------------===//
101 BumpPtrAllocator::BumpPtrAllocator() {
102 TheMemory
= malloc(4096);
103 ((MemRegion
*)TheMemory
)->Init(4096, 1, 0);
106 BumpPtrAllocator::~BumpPtrAllocator() {
107 ((MemRegion
*)TheMemory
)->Deallocate();
110 void BumpPtrAllocator::Reset() {
111 MemRegion
*MRP
= (MemRegion
*)TheMemory
;
112 MRP
= MRP
->DeallocateAllButLast();
113 MRP
->Init(4096, 1, 0);
117 void *BumpPtrAllocator::Allocate(size_t Size
, size_t Align
) {
118 MemRegion
*MRP
= (MemRegion
*)TheMemory
;
119 void *Ptr
= MRP
->Allocate(Size
, Align
, &MRP
);
124 void BumpPtrAllocator::PrintStats() const {
125 unsigned BytesUsed
= 0;
126 unsigned NumRegions
= 0;
127 const MemRegion
*R
= (MemRegion
*)TheMemory
;
128 for (; R
; R
= R
->getNext(), ++NumRegions
)
129 BytesUsed
+= R
->getNumBytesAllocated();
131 cerr
<< "\nNumber of memory regions: " << NumRegions
<< "\n";
132 cerr
<< "Bytes allocated: " << BytesUsed
<< "\n";
135 void llvm::PrintRecyclerStats(size_t Size
,
137 size_t FreeListSize
) {
138 cerr
<< "Recycler element size: " << Size
<< '\n';
139 cerr
<< "Recycler element alignment: " << Align
<< '\n';
140 cerr
<< "Number of elements free for recycling: " << FreeListSize
<< '\n';