1193323Sed//==- llvm/Support/RecyclingAllocator.h - Recycling Allocator ----*- C++ -*-==//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines the RecyclingAllocator class.  See the doxygen comment for
11193323Sed// RecyclingAllocator for more details on the implementation.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#ifndef LLVM_SUPPORT_RECYCLINGALLOCATOR_H
16193323Sed#define LLVM_SUPPORT_RECYCLINGALLOCATOR_H
17193323Sed
18193323Sed#include "llvm/Support/Recycler.h"
19193323Sed
20193323Sednamespace llvm {
21193323Sed
22193323Sed/// RecyclingAllocator - This class wraps an Allocator, adding the
23193323Sed/// functionality of recycling deleted objects.
24193323Sed///
25193323Sedtemplate<class AllocatorType, class T,
26193323Sed         size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
27193323Sedclass RecyclingAllocator {
28193323Sedprivate:
29193323Sed  /// Base - Implementation details.
30193323Sed  ///
31193323Sed  Recycler<T, Size, Align> Base;
32193323Sed
33193323Sed  /// Allocator - The wrapped allocator.
34193323Sed  ///
35193323Sed  AllocatorType Allocator;
36193323Sed
37193323Sedpublic:
38193323Sed  ~RecyclingAllocator() { Base.clear(Allocator); }
39193323Sed
40193323Sed  /// Allocate - Return a pointer to storage for an object of type
41193323Sed  /// SubClass. The storage may be either newly allocated or recycled.
42193323Sed  ///
43193323Sed  template<class SubClass>
44198953Srdivacky  SubClass *Allocate() { return Base.template Allocate<SubClass>(Allocator); }
45193323Sed
46193323Sed  T *Allocate() { return Base.Allocate(Allocator); }
47193323Sed
48193323Sed  /// Deallocate - Release storage for the pointed-to object. The
49193323Sed  /// storage will be kept track of and may be recycled.
50193323Sed  ///
51193323Sed  template<class SubClass>
52193323Sed  void Deallocate(SubClass* E) { return Base.Deallocate(Allocator, E); }
53193323Sed
54263509Sdim  void PrintStats() {
55263509Sdim    Allocator.PrintStats();
56263509Sdim    Base.PrintStats();
57263509Sdim  }
58193323Sed};
59193323Sed
60193323Sed}
61193323Sed
62205407Srdivackytemplate<class AllocatorType, class T, size_t Size, size_t Align>
63263509Sdiminline void *operator new(size_t size,
64205407Srdivacky                          llvm::RecyclingAllocator<AllocatorType,
65205407Srdivacky                                                   T, Size, Align> &Allocator) {
66263509Sdim  assert(size <= Size && "allocation size exceeded");
67205407Srdivacky  return Allocator.Allocate();
68205407Srdivacky}
69205407Srdivacky
70207618Srdivackytemplate<class AllocatorType, class T, size_t Size, size_t Align>
71207618Srdivackyinline void operator delete(void *E,
72207618Srdivacky                            llvm::RecyclingAllocator<AllocatorType,
73207618Srdivacky                                                     T, Size, Align> &A) {
74207618Srdivacky  A.Deallocate(E);
75207618Srdivacky}
76207618Srdivacky
77193323Sed#endif
78