X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FAllocator.h;h=7a7e4c0a13e2ee1f5052f619a7f69ac50d3991e0;hb=255907042245b77779e3e38c5ce66901866cabe5;hp=5565c1ccf129686623f36448b593362ee031a9c6;hpb=47b284ce3539ef216e0ab994f4b7d762cfb1c69a;p=oota-llvm.git diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index 5565c1ccf12..7a7e4c0a13e 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -32,12 +32,6 @@ #include namespace llvm { -template struct ReferenceAdder { - typedef T &result; -}; -template struct ReferenceAdder { - typedef T result; -}; /// \brief CRTP base class providing obvious overloads for the core \c /// Allocate() methods of LLVM-style allocators. @@ -78,46 +72,22 @@ public: // The rest of these methods are helpers that redirect to one of the above // core methods. - /// \brief Allocate space for one object without constructing it. - template T *Allocate() { - return static_cast(Allocate(sizeof(T), AlignOf::Alignment)); - } - - /// \brief Allocate space for an array of objects without constructing them. - template T *Allocate(size_t Num) { + /// \brief Allocate space for a sequence of objects without constructing them. + template T *Allocate(size_t Num = 1) { return static_cast(Allocate(Num * sizeof(T), AlignOf::Alignment)); } - /// \brief Allocate space for an array of objects with the specified alignment - /// and without constructing them. - template T *Allocate(size_t Num, size_t Alignment) { - // Round EltSize up to the specified alignment. - size_t EltSize = (sizeof(T) + Alignment - 1) & (-Alignment); - return static_cast(Allocate(Num * EltSize, Alignment)); - } - - /// \brief Deallocate space for one object without destroying it. + /// \brief Deallocate space for a sequence of objects without constructing them. template typename std::enable_if< !std::is_same::type, void>::value, void>::type - Deallocate(T *Ptr) { - Deallocate(static_cast(Ptr), sizeof(T)); - } - - /// \brief Allocate space for an array of objects without constructing them. - template - typename std::enable_if< - !std::is_same::type, void>::value, void>::type - Deallocate(T *Ptr, size_t Num) { + Deallocate(T *Ptr, size_t Num = 1) { Deallocate(static_cast(Ptr), Num * sizeof(T)); } }; class MallocAllocator : public AllocatorBase { public: - MallocAllocator() {} - ~MallocAllocator() {} - void Reset() {} void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); } @@ -135,19 +105,6 @@ public: void PrintStats() const {} }; -/// MallocSlabAllocator - The default slab allocator for the bump allocator -/// is an adapter class for MallocAllocator that just forwards the method -/// calls and translates the arguments. -class MallocSlabAllocator { - /// Allocator - The underlying allocator that we forward to. - /// - MallocAllocator Allocator; - -public: - void *Allocate(size_t Size) { return Allocator.Allocate(Size, 0); } - void Deallocate(void *Slab, size_t Size) { Allocator.Deallocate(Slab, Size); } -}; - namespace detail { // We call out to an external function to actually print the message as the @@ -167,17 +124,14 @@ void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated, /// Note that this also has a threshold for forcing allocations above a certain /// size into their own slab. /// -/// The BumpPtrAllocatorImpl template defaults to using a MallocSlabAllocator +/// The BumpPtrAllocatorImpl template defaults to using a MallocAllocator /// object, which wraps malloc, to allocate memory, but it can be changed to /// use a custom allocator. -template class BumpPtrAllocatorImpl : public AllocatorBase< BumpPtrAllocatorImpl> { - BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION; - void operator=(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION; - public: static_assert(SizeThreshold <= SlabSize, "The SizeThreshold must be at most the SlabSize to ensure " @@ -190,11 +144,43 @@ public: BumpPtrAllocatorImpl(T &&Allocator) : CurPtr(nullptr), End(nullptr), BytesAllocated(0), Allocator(std::forward(Allocator)) {} + + // Manually implement a move constructor as we must clear the old allocators + // slabs as a matter of correctness. + BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old) + : CurPtr(Old.CurPtr), End(Old.End), Slabs(std::move(Old.Slabs)), + CustomSizedSlabs(std::move(Old.CustomSizedSlabs)), + BytesAllocated(Old.BytesAllocated), + Allocator(std::move(Old.Allocator)) { + Old.CurPtr = Old.End = nullptr; + Old.BytesAllocated = 0; + Old.Slabs.clear(); + Old.CustomSizedSlabs.clear(); + } + ~BumpPtrAllocatorImpl() { DeallocateSlabs(Slabs.begin(), Slabs.end()); DeallocateCustomSizedSlabs(); } + BumpPtrAllocatorImpl &operator=(BumpPtrAllocatorImpl &&RHS) { + DeallocateSlabs(Slabs.begin(), Slabs.end()); + DeallocateCustomSizedSlabs(); + + CurPtr = RHS.CurPtr; + End = RHS.End; + BytesAllocated = RHS.BytesAllocated; + Slabs = std::move(RHS.Slabs); + CustomSizedSlabs = std::move(RHS.CustomSizedSlabs); + Allocator = std::move(RHS.Allocator); + + RHS.CurPtr = RHS.End = nullptr; + RHS.BytesAllocated = 0; + RHS.Slabs.clear(); + RHS.CustomSizedSlabs.clear(); + return *this; + } + /// \brief Deallocate all but the current slab and reset the current pointer /// to the beginning of it, freeing all memory allocated so far. void Reset() { @@ -241,7 +227,7 @@ public: // If Size is really big, allocate a separate slab for it. size_t PaddedSize = Size + Alignment - 1; if (PaddedSize > SizeThreshold) { - void *NewSlab = Allocator.Allocate(PaddedSize); + void *NewSlab = Allocator.Allocate(PaddedSize, 0); CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize)); Ptr = alignPtr((char *)NewSlab, Alignment); @@ -319,7 +305,7 @@ private: void StartNewSlab() { size_t AllocatedSlabSize = computeSlabSize(Slabs.size()); - void *NewSlab = Allocator.Allocate(AllocatedSlabSize); + void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0); Slabs.push_back(NewSlab); CurPtr = (char *)(NewSlab); End = ((char *)NewSlab) + AllocatedSlabSize; @@ -373,9 +359,15 @@ template class SpecificBumpPtrAllocator { public: SpecificBumpPtrAllocator() : Allocator() {} - + SpecificBumpPtrAllocator(SpecificBumpPtrAllocator &&Old) + : Allocator(std::move(Old.Allocator)) {} ~SpecificBumpPtrAllocator() { DestroyAll(); } + SpecificBumpPtrAllocator &operator=(SpecificBumpPtrAllocator &&RHS) { + Allocator = std::move(RHS.Allocator); + return *this; + } + /// Call the destructor of each allocated object and deallocate all but the /// current slab and reset the current pointer to the beginning of it, freeing /// all memory allocated so far. @@ -408,8 +400,6 @@ public: /// \brief Allocate space for an array of objects without constructing them. T *Allocate(size_t num = 1) { return Allocator.Allocate(num); } - -private: }; } // end namespace llvm