Introduce another Reset() method in BumpPtrAllocator that calls a destructor
authorTorok Edwin <edwintorok@gmail.com>
Tue, 30 Mar 2010 10:08:26 +0000 (10:08 +0000)
committerTorok Edwin <edwintorok@gmail.com>
Tue, 30 Mar 2010 10:08:26 +0000 (10:08 +0000)
on all objects it has allocated, if they are all of the same size and alignment.
Use this to destruct all VNInfos allocated in LiveIntervalAnalysis (PR6653).

valnos is not reliable for this purpose, as seen in r99400
(which still leaked, and sometimes caused double frees).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99881 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/Allocator.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/Support/Allocator.cpp

index b1f59dc05e7bb892cb2c2c614efc2140c10170dc..a58b9db27faafc3b4aa58adb3c5ae9f75eb17ee7 100644 (file)
@@ -134,6 +134,7 @@ class BumpPtrAllocator {
   static MallocSlabAllocator DefaultSlabAllocator;
 
 public:
+  typedef void (*DTorFunction)(void*);
   BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
                    SlabAllocator &allocator = DefaultSlabAllocator);
   ~BumpPtrAllocator();
@@ -142,6 +143,11 @@ public:
   /// to the beginning of it, freeing all memory allocated so far.
   void Reset();
 
+  /// Reset - like Reset(), but call DTorFunction for each allocated
+  /// object. This assumes that all objects allocated with this allocator
+  /// had the same size and alignment specified here.
+  void Reset(size_t Size, size_t Alignment, DTorFunction DTor);
+
   /// Allocate - Allocate space at the specified alignment.
   ///
   void *Allocate(size_t Size, size_t Alignment);
index e657c46c721eb69b180a8931b05ebc50714889a8..53366b9f0741349a6b3e3474f756a8c5223b9197 100644 (file)
@@ -82,6 +82,11 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
+static void VNInfoDTor(void* Ptr)
+{
+   reinterpret_cast<VNInfo*>(Ptr)->~VNInfo();
+}
+
 void LiveIntervals::releaseMemory() {
   // Free the live intervals themselves.
   for (DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.begin(),
@@ -91,7 +96,7 @@ void LiveIntervals::releaseMemory() {
   r2iMap_.clear();
 
   // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
-  VNInfoAllocator.Reset();
+  VNInfoAllocator.Reset((unsigned)sizeof(VNInfo), alignof<VNInfo>(), VNInfoDTor);
   while (!CloneMIs.empty()) {
     MachineInstr *MI = CloneMIs.back();
     CloneMIs.pop_back();
index 31b45c8d4aae77538940f8f1b9e948f7f2726e23..7433247c23796de3b94198bd19640654f89280b7 100644 (file)
@@ -78,6 +78,21 @@ void BumpPtrAllocator::Reset() {
   End = ((char*)CurSlab) + CurSlab->Size;
 }
 
+void BumpPtrAllocator::Reset(size_t Size, size_t Alignment, DTorFunction DTor) {
+  if (Alignment == 0) Alignment = 1;
+  MemSlab *Slab = CurSlab;
+  while (Slab) {
+    char *End = Slab == CurSlab ? CurPtr : (char*)Slab + Slab->Size;
+    for (char *Ptr = (char*)Slab+1; Ptr < End; Ptr += Size) {
+       Ptr = AlignPtr(Ptr, Alignment);
+       if (Ptr + Size <= End)
+           DTor(Ptr);
+    }
+    Slab = Slab->NextPtr;
+  }
+  Reset();
+}
+
 /// Allocate - Allocate space at the specified alignment.
 ///
 void *BumpPtrAllocator::Allocate(size_t Size, size_t Alignment) {