00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef LLVM_SUPPORT_RECYCLER_H
00016 #define LLVM_SUPPORT_RECYCLER_H
00017
00018 #include "llvm/ADT/ilist.h"
00019 #include "llvm/Support/AlignOf.h"
00020 #include <cassert>
00021
00022 namespace llvm {
00023
00027 void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize);
00028
00032 struct RecyclerStruct {
00033 RecyclerStruct *Prev, *Next;
00034 };
00035
00036 template<>
00037 struct ilist_traits<RecyclerStruct> :
00038 public ilist_default_traits<RecyclerStruct> {
00039 static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; }
00040 static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; }
00041 static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; }
00042 static void setNext(RecyclerStruct *t, RecyclerStruct *n) { t->Next = n; }
00043
00044 mutable RecyclerStruct Sentinel;
00045 RecyclerStruct *createSentinel() const {
00046 return &Sentinel;
00047 }
00048 static void destroySentinel(RecyclerStruct *) {}
00049
00050 RecyclerStruct *provideInitialHead() const { return createSentinel(); }
00051 RecyclerStruct *ensureHead(RecyclerStruct*) const { return createSentinel(); }
00052 static void noteHead(RecyclerStruct*, RecyclerStruct*) {}
00053
00054 static void deleteNode(RecyclerStruct *) {
00055 assert(0 && "Recycler's ilist_traits shouldn't see a deleteNode call!");
00056 }
00057 };
00058
00063 template<class T, size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
00064 class Recycler {
00068 iplist<RecyclerStruct> FreeList;
00069
00070 public:
00071 ~Recycler() {
00072
00073
00074
00075 assert(FreeList.empty() && "Non-empty recycler deleted!");
00076 }
00077
00081 template<class AllocatorType>
00082 void clear(AllocatorType &Allocator) {
00083 while (!FreeList.empty()) {
00084 T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin()));
00085 Allocator.Deallocate(t);
00086 }
00087 }
00088
00089 template<class SubClass, class AllocatorType>
00090 SubClass *Allocate(AllocatorType &Allocator) {
00091 assert(sizeof(SubClass) <= Size &&
00092 "Recycler allocation size is less than object size!");
00093 assert(AlignOf<SubClass>::Alignment <= Align &&
00094 "Recycler allocation alignment is less than object alignment!");
00095 return !FreeList.empty() ?
00096 reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
00097 static_cast<SubClass *>(Allocator.Allocate(Size, Align));
00098 }
00099
00100 template<class AllocatorType>
00101 T *Allocate(AllocatorType &Allocator) {
00102 return Allocate<T>(Allocator);
00103 }
00104
00105 template<class SubClass, class AllocatorType>
00106 void Deallocate(AllocatorType & , SubClass* Element) {
00107 FreeList.push_front(reinterpret_cast<RecyclerStruct *>(Element));
00108 }
00109
00110 void PrintStats() {
00111 PrintRecyclerStats(Size, Align, FreeList.size());
00112 }
00113 };
00114
00115 }
00116
00117 #endif