From 9f617d64c5f3f2a0949f359f63b1cb3bff4b3a9b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 29 Oct 2006 22:08:03 +0000 Subject: [PATCH] Add a new llvm::Allocator abstraction, which will be used by a container I'm about to add. This is similar to, but necessarily different than, the STL allocator class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31285 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/Allocator.h | 48 ++++++++++++++ lib/Support/Allocator.cpp | 106 +++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 include/llvm/Support/Allocator.h create mode 100644 lib/Support/Allocator.cpp diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h new file mode 100644 index 00000000000..527d4c6e2cb --- /dev/null +++ b/include/llvm/Support/Allocator.h @@ -0,0 +1,48 @@ +//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===// +// +// 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 defines the MallocAllocator and BumpPtrAllocator interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ALLOCATOR_H +#define LLVM_SUPPORT_ALLOCATOR_H + +#include + +namespace llvm { + +class MallocAllocator { +public: + MallocAllocator() {} + ~MallocAllocator() {} + + void *Allocate(unsigned Size, unsigned Alignment) { return malloc(Size); } + void Deallocate(void *Ptr) { free(Ptr); } + void PrintStats() const {} +}; + +/// BumpPtrAllocator - This allocator is useful for containers that need very +/// simple memory allocation strategies. In particular, this just keeps +/// allocating memory, and never deletes it until the entire block is dead. This +/// makes allocation speedy, but must only be used when the trade-off is ok. +class BumpPtrAllocator { + void *TheMemory; +public: + BumpPtrAllocator(); + ~BumpPtrAllocator(); + + void *Allocate(unsigned Size, unsigned Alignment); + void Deallocate(void *Ptr) {} + void PrintStats() const; +}; + +} // end namespace clang + +#endif diff --git a/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp new file mode 100644 index 00000000000..0d0367a6f13 --- /dev/null +++ b/lib/Support/Allocator.cpp @@ -0,0 +1,106 @@ +//===--- Allocator.cpp - Simple memory allocation abstraction -------------===// +// +// 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 implements the BumpPtrAllocator interface. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Allocator.h" +#include +using namespace llvm; + +//===----------------------------------------------------------------------===// +// MemRegion class implementation +//===----------------------------------------------------------------------===// + +namespace { +/// MemRegion - This is one chunk of the BumpPtrAllocator. +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); + + // Align NextPtr. + 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; + } + + /// 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); + + // If there is space in this region, return it. + if (unsigned(NextPtr+AllocSize-(char*)this) <= RegionSize) { + void *Result = NextPtr; + NextPtr += AllocSize; + return Result; + } + + // Otherwise, we have to allocate a new chunk. Create one twice as big as + // this one. + MemRegion *NewRegion = (MemRegion *)malloc(RegionSize*2); + NewRegion->Init(RegionSize*2, Alignment, this); + + // Update the current "first region" pointer to point to the new region. + *RegPtr = NewRegion; + + // Try allocating from it now. + return NewRegion->Allocate(AllocSize, Alignment, RegPtr); + } + + /// Deallocate - Release all memory for this region to the system. + /// + void Deallocate() { + MemRegion *next = Next; + free(this); + if (next) + next->Deallocate(); + } +}; +} + +//===----------------------------------------------------------------------===// +// BumpPtrAllocator class implementation +//===----------------------------------------------------------------------===// + +BumpPtrAllocator::BumpPtrAllocator() { + TheMemory = malloc(4096); + ((MemRegion*)TheMemory)->Init(4096, 1, 0); +} + +BumpPtrAllocator::~BumpPtrAllocator() { + ((MemRegion*)TheMemory)->Deallocate(); +} + +void *BumpPtrAllocator::Allocate(unsigned Size, unsigned Align) { + return ((MemRegion*)TheMemory)->Allocate(Size, Align,(MemRegion**)&TheMemory); +} + +void BumpPtrAllocator::PrintStats() const { + unsigned BytesUsed = 0; + unsigned NumRegions = 0; + const MemRegion *R = (MemRegion*)TheMemory; + for (; R; R = R->getNext(), ++NumRegions) + BytesUsed += R->getNumBytesAllocated(); + + std::cerr << "\nNumber of memory regions: " << NumRegions << "\n"; + std::cerr << "Bytes allocated: " << BytesUsed << "\n"; +} -- 2.34.1