LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Allocator.cpp

Go to the documentation of this file.
00001 //===--- Allocator.cpp - Simple memory allocation abstraction -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the BumpPtrAllocator interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Support/Allocator.h"
00015 #include "llvm/Support/Recycler.h"
00016 #include "llvm/Support/DataTypes.h"
00017 #include "llvm/Support/Streams.h"
00018 #include <ostream>
00019 using namespace llvm;
00020 
00021 //===----------------------------------------------------------------------===//
00022 // MemRegion class implementation
00023 //===----------------------------------------------------------------------===//
00024 
00025 namespace {
00026 /// MemRegion - This is one chunk of the BumpPtrAllocator.
00027 class MemRegion {
00028   unsigned RegionSize;
00029   MemRegion *Next;
00030   char *NextPtr;
00031 public:
00032   void Init(unsigned size, unsigned Alignment, MemRegion *next) {
00033     RegionSize = size;
00034     Next = next;
00035     NextPtr = (char*)(this+1);
00036     
00037     // Align NextPtr.
00038     NextPtr = (char*)((intptr_t)(NextPtr+Alignment-1) &
00039                       ~(intptr_t)(Alignment-1));
00040   }
00041   
00042   const MemRegion *getNext() const { return Next; }
00043   unsigned getNumBytesAllocated() const {
00044     return NextPtr-(const char*)this;
00045   }
00046   
00047   /// Allocate - Allocate and return at least the specified number of bytes.
00048   ///
00049   void *Allocate(size_t AllocSize, size_t Alignment, MemRegion **RegPtr) {
00050     
00051     char* Result = (char*) (((uintptr_t) (NextPtr+Alignment-1)) 
00052                             & ~((uintptr_t) Alignment-1));
00053 
00054     // Speculate the new value of NextPtr.
00055     char* NextPtrTmp = Result + AllocSize;
00056     
00057     // If we are still within the current region, return Result.
00058     if (unsigned (NextPtrTmp - (char*) this) <= RegionSize) {
00059       NextPtr = NextPtrTmp;
00060       return Result;
00061     }
00062     
00063     // Otherwise, we have to allocate a new chunk.  Create one twice as big as
00064     // this one.
00065     MemRegion *NewRegion = (MemRegion *)malloc(RegionSize*2);
00066     NewRegion->Init(RegionSize*2, Alignment, this);
00067 
00068     // Update the current "first region" pointer  to point to the new region.
00069     *RegPtr = NewRegion;
00070     
00071     // Try allocating from it now.
00072     return NewRegion->Allocate(AllocSize, Alignment, RegPtr);
00073   }
00074   
00075   /// Deallocate - Recursively release all memory for this and its next regions
00076   /// to the system.
00077   void Deallocate() {
00078     MemRegion *next = Next;
00079     free(this);
00080     if (next)
00081       next->Deallocate();
00082   }
00083 
00084   /// DeallocateAllButLast - Recursively release all memory for this and its
00085   /// next regions to the system stopping at the last region in the list.
00086   /// Returns the pointer to the last region.
00087   MemRegion *DeallocateAllButLast() {
00088     MemRegion *next = Next;
00089     if (!next)
00090       return this;
00091     free(this);
00092     return next->DeallocateAllButLast();
00093   }
00094 };
00095 }
00096 
00097 //===----------------------------------------------------------------------===//
00098 // BumpPtrAllocator class implementation
00099 //===----------------------------------------------------------------------===//
00100 
00101 BumpPtrAllocator::BumpPtrAllocator() {
00102   TheMemory = malloc(4096);
00103   ((MemRegion*)TheMemory)->Init(4096, 1, 0);
00104 }
00105 
00106 BumpPtrAllocator::~BumpPtrAllocator() {
00107   ((MemRegion*)TheMemory)->Deallocate();
00108 }
00109 
00110 void BumpPtrAllocator::Reset() {
00111   MemRegion *MRP = (MemRegion*)TheMemory;
00112   MRP = MRP->DeallocateAllButLast();
00113   MRP->Init(4096, 1, 0);
00114   TheMemory = MRP;
00115 }
00116 
00117 void *BumpPtrAllocator::Allocate(size_t Size, size_t Align) {
00118   MemRegion *MRP = (MemRegion*)TheMemory;
00119   void *Ptr = MRP->Allocate(Size, Align, &MRP);
00120   TheMemory = MRP;
00121   return Ptr;
00122 }
00123 
00124 void BumpPtrAllocator::PrintStats() const {
00125   unsigned BytesUsed = 0;
00126   unsigned NumRegions = 0;
00127   const MemRegion *R = (MemRegion*)TheMemory;
00128   for (; R; R = R->getNext(), ++NumRegions)
00129     BytesUsed += R->getNumBytesAllocated();
00130 
00131   cerr << "\nNumber of memory regions: " << NumRegions << "\n";
00132   cerr << "Bytes allocated: " << BytesUsed << "\n";
00133 }
00134 
00135 void llvm::PrintRecyclerStats(size_t Size,
00136                               size_t Align,
00137                               size_t FreeListSize) {
00138   cerr << "Recycler element size: " << Size << '\n';
00139   cerr << "Recycler element alignment: " << Align << '\n';
00140   cerr << "Number of elements free for recycling: " << FreeListSize << '\n';
00141 }



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.