[llvm] r206372 - [Allocator] Make BumpPtrAllocator movable and move assignable.

Chandler Carruth chandlerc at gmail.com
Wed Apr 16 03:48:27 PDT 2014


Author: chandlerc
Date: Wed Apr 16 05:48:27 2014
New Revision: 206372

URL: http://llvm.org/viewvc/llvm-project?rev=206372&view=rev
Log:
[Allocator] Make BumpPtrAllocator movable and move assignable.

Modified:
    llvm/trunk/include/llvm/Support/Allocator.h
    llvm/trunk/unittests/Support/AllocatorTest.cpp

Modified: llvm/trunk/include/llvm/Support/Allocator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Allocator.h?rev=206372&r1=206371&r2=206372&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Allocator.h (original)
+++ llvm/trunk/include/llvm/Support/Allocator.h Wed Apr 16 05:48:27 2014
@@ -138,9 +138,6 @@ template <typename AllocatorT = MallocAl
 class BumpPtrAllocatorImpl
     : public AllocatorBase<
           BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold>> {
-  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 "
@@ -153,11 +150,43 @@ public:
   BumpPtrAllocatorImpl(T &&Allocator)
       : CurPtr(nullptr), End(nullptr), BytesAllocated(0),
         Allocator(std::forward<T &&>(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() {

Modified: llvm/trunk/unittests/Support/AllocatorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/AllocatorTest.cpp?rev=206372&r1=206371&r2=206372&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/AllocatorTest.cpp (original)
+++ llvm/trunk/unittests/Support/AllocatorTest.cpp Wed Apr 16 05:48:27 2014
@@ -29,6 +29,21 @@ TEST(AllocatorTest, Basics) {
   EXPECT_EQ(2, b[9]);
   EXPECT_EQ(3, *c);
   EXPECT_EQ(1U, Alloc.GetNumSlabs());
+
+  BumpPtrAllocator Alloc2 = std::move(Alloc);
+  EXPECT_EQ(0U, Alloc.GetNumSlabs());
+  EXPECT_EQ(1U, Alloc2.GetNumSlabs());
+
+  // Make sure the old pointers still work. These are especially interesting
+  // under ASan or Valgrind.
+  EXPECT_EQ(1, *a);
+  EXPECT_EQ(2, b[0]);
+  EXPECT_EQ(2, b[9]);
+  EXPECT_EQ(3, *c);
+
+  Alloc = std::move(Alloc2);
+  EXPECT_EQ(0U, Alloc2.GetNumSlabs());
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
 }
 
 // Allocate enough bytes to create three slabs.





More information about the llvm-commits mailing list