[llvm] d3bc86c - [Allocator] Make Deallocate() pass alignment and make it use (de)allocate_buffer

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Sat May 2 07:09:10 PDT 2020


Author: Benjamin Kramer
Date: 2020-05-02T16:08:46+02:00
New Revision: d3bc86c2ed579c3b854d37c114a85901ed8cfb9a

URL: https://github.com/llvm/llvm-project/commit/d3bc86c2ed579c3b854d37c114a85901ed8cfb9a
DIFF: https://github.com/llvm/llvm-project/commit/d3bc86c2ed579c3b854d37c114a85901ed8cfb9a.diff

LOG: [Allocator] Make Deallocate() pass alignment and make it use (de)allocate_buffer

This lets it use sized deallocation and make more efficient alignment
decisions. Also adjust BumpPtrAllocator to always allocate at
alignof(std::max_align_t).

Added: 
    

Modified: 
    llvm/include/llvm/ADT/StringMapEntry.h
    llvm/include/llvm/Support/Allocator.h
    llvm/include/llvm/Support/AllocatorBase.h
    llvm/include/llvm/Support/YAMLParser.h
    llvm/unittests/ADT/StringMapTest.cpp
    llvm/unittests/Support/AllocatorTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
index 19638f35d3e6..ea3aad6f1cb1 100644
--- a/llvm/include/llvm/ADT/StringMapEntry.h
+++ b/llvm/include/llvm/ADT/StringMapEntry.h
@@ -125,7 +125,8 @@ class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
     // Free memory referenced by the item.
     size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1;
     this->~StringMapEntry();
-    allocator.Deallocate(static_cast<void *>(this), AllocSize);
+    allocator.Deallocate(static_cast<void *>(this), AllocSize,
+                         alignof(StringMapEntry));
   }
 };
 

diff  --git a/llvm/include/llvm/Support/Allocator.h b/llvm/include/llvm/Support/Allocator.h
index be09bd635219..40c967ccc485 100644
--- a/llvm/include/llvm/Support/Allocator.h
+++ b/llvm/include/llvm/Support/Allocator.h
@@ -170,7 +170,7 @@ class BumpPtrAllocatorImpl
     // If Size is really big, allocate a separate slab for it.
     size_t PaddedSize = SizeToAllocate + Alignment.value() - 1;
     if (PaddedSize > SizeThreshold) {
-      void *NewSlab = Allocator.Allocate(PaddedSize, 0);
+      void *NewSlab = Allocator.Allocate(PaddedSize, alignof(std::max_align_t));
       // We own the new slab and don't want anyone reading anyting other than
       // pieces returned from this method.  So poison the whole slab.
       __asan_poison_memory_region(NewSlab, PaddedSize);
@@ -208,7 +208,7 @@ class BumpPtrAllocatorImpl
   // Bump pointer allocators are expected to never free their storage; and
   // clients expect pointers to remain valid for non-dereferencing uses even
   // after deallocation.
-  void Deallocate(const void *Ptr, size_t Size) {
+  void Deallocate(const void *Ptr, size_t Size, size_t /*Alignment*/) {
     __asan_poison_memory_region(Ptr, Size);
   }
 
@@ -332,7 +332,8 @@ class BumpPtrAllocatorImpl
   void StartNewSlab() {
     size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
 
-    void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
+    void *NewSlab =
+        Allocator.Allocate(AllocatedSlabSize, alignof(std::max_align_t));
     // We own the new slab and don't want anyone reading anything other than
     // pieces returned from this method.  So poison the whole slab.
     __asan_poison_memory_region(NewSlab, AllocatedSlabSize);
@@ -348,7 +349,7 @@ class BumpPtrAllocatorImpl
     for (; I != E; ++I) {
       size_t AllocatedSlabSize =
           computeSlabSize(std::distance(Slabs.begin(), I));
-      Allocator.Deallocate(*I, AllocatedSlabSize);
+      Allocator.Deallocate(*I, AllocatedSlabSize, alignof(std::max_align_t));
     }
   }
 
@@ -357,7 +358,7 @@ class BumpPtrAllocatorImpl
     for (auto &PtrAndSize : CustomSizedSlabs) {
       void *Ptr = PtrAndSize.first;
       size_t Size = PtrAndSize.second;
-      Allocator.Deallocate(Ptr, Size);
+      Allocator.Deallocate(Ptr, Size, alignof(std::max_align_t));
     }
   }
 
@@ -434,17 +435,8 @@ void *
 operator new(size_t Size,
              llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold,
                                         GrowthDelay> &Allocator) {
-  struct S {
-    char c;
-    union {
-      double D;
-      long double LD;
-      long long L;
-      void *P;
-    } x;
-  };
-  return Allocator.Allocate(
-      Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
+  return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
+                                           alignof(std::max_align_t)));
 }
 
 template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,

diff  --git a/llvm/include/llvm/Support/AllocatorBase.h b/llvm/include/llvm/Support/AllocatorBase.h
index 7f430040ddfb..e5549d111622 100644
--- a/llvm/include/llvm/Support/AllocatorBase.h
+++ b/llvm/include/llvm/Support/AllocatorBase.h
@@ -48,16 +48,17 @@ template <typename DerivedT> class AllocatorBase {
 
   /// Deallocate \a Ptr to \a Size bytes of memory allocated by this
   /// allocator.
-  void Deallocate(const void *Ptr, size_t Size) {
+  void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
 #ifdef __clang__
-    static_assert(static_cast<void (AllocatorBase::*)(const void *, size_t)>(
-                      &AllocatorBase::Deallocate) !=
-                      static_cast<void (DerivedT::*)(const void *, size_t)>(
-                          &DerivedT::Deallocate),
-                  "Class derives from AllocatorBase without implementing the "
-                  "core Deallocate(void *) overload!");
+    static_assert(
+        static_cast<void (AllocatorBase::*)(const void *, size_t, size_t)>(
+            &AllocatorBase::Deallocate) !=
+            static_cast<void (DerivedT::*)(const void *, size_t, size_t)>(
+                &DerivedT::Deallocate),
+        "Class derives from AllocatorBase without implementing the "
+        "core Deallocate(void *) overload!");
 #endif
-    return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size);
+    return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size, Alignment);
   }
 
   // The rest of these methods are helpers that redirect to one of the above
@@ -72,7 +73,7 @@ template <typename DerivedT> class AllocatorBase {
   template <typename T>
   std::enable_if_t<!std::is_same<std::remove_cv_t<T>, void>::value, void>
   Deallocate(T *Ptr, size_t Num = 1) {
-    Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T));
+    Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T), alignof(T));
   }
 };
 
@@ -80,16 +81,15 @@ class MallocAllocator : public AllocatorBase<MallocAllocator> {
 public:
   void Reset() {}
 
-  LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size,
-                                                size_t /*Alignment*/) {
-    return safe_malloc(Size);
+  LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
+    return allocate_buffer(Size, Alignment);
   }
 
   // Pull in base class overloads.
   using AllocatorBase<MallocAllocator>::Allocate;
 
-  void Deallocate(const void *Ptr, size_t /*Size*/) {
-    free(const_cast<void *>(Ptr));
+  void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
+    deallocate_buffer(const_cast<void *>(Ptr), Size, Alignment);
   }
 
   // Pull in base class overloads.

diff  --git a/llvm/include/llvm/Support/YAMLParser.h b/llvm/include/llvm/Support/YAMLParser.h
index 3570119a3bfd..53009d7ff4aa 100644
--- a/llvm/include/llvm/Support/YAMLParser.h
+++ b/llvm/include/llvm/Support/YAMLParser.h
@@ -139,7 +139,7 @@ class Node {
 
   void operator delete(void *Ptr, BumpPtrAllocator &Alloc,
                        size_t Size) noexcept {
-    Alloc.Deallocate(Ptr, Size);
+    Alloc.Deallocate(Ptr, Size, 0);
   }
 
   void operator delete(void *) noexcept = delete;

diff  --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index 2cad2c19c5bb..73c91f5fdd39 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -230,7 +230,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
           StringRef(testKeyFirst, testKeyLength), Allocator, 1u);
   EXPECT_STREQ(testKey, entry->first().data());
   EXPECT_EQ(1u, entry->second);
-  free(entry);
+  entry->Destroy(Allocator);
 }
 
 // Test insert() method.

diff  --git a/llvm/unittests/Support/AllocatorTest.cpp b/llvm/unittests/Support/AllocatorTest.cpp
index 57c3252fc701..c41f597c404d 100644
--- a/llvm/unittests/Support/AllocatorTest.cpp
+++ b/llvm/unittests/Support/AllocatorTest.cpp
@@ -206,7 +206,7 @@ class MockSlabAllocator {
     return Slab;
   }
 
-  void Deallocate(void *Slab, size_t Size) {
+  void Deallocate(void *Slab, size_t /*Size*/, size_t /*Alignment*/) {
     free(((void**)Slab)[-1]);
   }
 


        


More information about the llvm-commits mailing list