llvm-6502/include/llvm/Support/Recycler.h
Dan Gohman e14d81deeb Add some basic Pool-allocation infrastructure. This adds a Recycler class,
for handling bookkeeping for deleted objects, as well as the alist class
template, for keeping lists of objects allocated from Recyclers, and some
related utilities.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53210 91177308-0d34-0410-b5e6-96231b3b80d8
2008-07-07 22:58:06 +00:00

98 lines
2.9 KiB
C++

//==- llvm/Support/Recycler.h - Recycling Allocator --------------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the Recycler class template. See the doxygen comment for
// Recycler for more details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_RECYCLER_H
#define LLVM_SUPPORT_RECYCLER_H
#include <cassert>
#include "llvm/ADT/alist_node.h"
namespace llvm {
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
/// printing statistics.
///
void PrintRecyclerStats(size_t LargestTypeSize, size_t FreeListSize);
/// Recycler - This class manages a linked-list of deallocated nodes
/// and facilitates reusing deallocated memory in place of allocating
/// new memory. The objects it allocates are stored in alist_node
/// containers, so they may be used in alists.
///
template<class T, class LargestT = T>
class Recycler {
typedef alist_node<T, LargestT> NodeTy;
/// FreeListTraits - ilist traits for FreeList.
///
struct FreeListTraits : ilist_traits<alist_node<T, LargestT> > {
NodeTy &getSentinel() { return this->Sentinel; }
};
/// FreeList - Doubly-linked list of nodes that have deleted contents and
/// are not in active use.
///
iplist<NodeTy, FreeListTraits> FreeList;
/// CreateNewNode - Allocate a new node object and initialize its
/// prev and next pointers to 0.
///
template<class AllocatorType>
NodeTy *CreateNewNode(AllocatorType &Allocator) {
// Note that we're calling new on the *node*, to initialize its
// Next/Prev pointers, not new on the end-user object.
return new (Allocator.Allocate<NodeTy>()) NodeTy();
}
public:
~Recycler() { assert(FreeList.empty()); }
template<class AllocatorType>
void clear(AllocatorType &Allocator) {
while (!FreeList.empty())
Allocator.Deallocate(FreeList.remove(FreeList.begin()));
}
template<class SubClass, class AllocatorType>
SubClass *Allocate(AllocatorType &Allocator) {
NodeTy *N = !FreeList.empty() ?
FreeList.remove(FreeList.front()) :
CreateNewNode(Allocator);
assert(N->getPrev() == 0);
assert(N->getNext() == 0);
return N->getElement((SubClass*)0);
}
template<class AllocatorType>
T *Allocate(AllocatorType &Allocator) {
return Allocate<T>(Allocator);
}
template<class SubClass, class AllocatorType>
void Deallocate(AllocatorType &Allocator, SubClass* Element) {
NodeTy *N = NodeTy::getNode(Element);
assert(N->getPrev() == 0);
assert(N->getNext() == 0);
FreeList.push_front(N);
}
void PrintStats() {
PrintRecyclerStats(sizeof(LargestT), FreeList.size());
}
};
}
#endif