[compiler-rt] a1e325c - [scudo] Lazy initialize the PageMap while page releasing

Chia-hung Duan via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 28 14:13:16 PDT 2022


Author: Chia-hung Duan
Date: 2022-10-28T20:29:17Z
New Revision: a1e325ce7ccee3eeaa6559e465d907e0a5a28a69

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

LOG: [scudo] Lazy initialize the PageMap while page releasing

We allocate the page map before knowing if there're groups can be
released. This may result in many redundant map()/unmap() operations if
there's no page to release.

Make the page map be lazy initialized.

Differential Revision: https://reviews.llvm.org/D136873

Added: 
    

Modified: 
    compiler-rt/lib/scudo/standalone/primary32.h
    compiler-rt/lib/scudo/standalone/primary64.h
    compiler-rt/lib/scudo/standalone/release.h
    compiler-rt/lib/scudo/standalone/tests/release_test.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h
index 7f608aeac2962..6e791a127df66 100644
--- a/compiler-rt/lib/scudo/standalone/primary32.h
+++ b/compiler-rt/lib/scudo/standalone/primary32.h
@@ -725,6 +725,9 @@ template <typename Config> class SizeClassAllocator32 {
       Context.markFreeBlocks(BG.Batches, DecompactPtr, Base);
     }
 
+    if (!Context.hasBlockMarked())
+      return 0;
+
     auto SkipRegion = [this, First, ClassId](uptr RegionIndex) {
       return (PossibleRegions[First + RegionIndex] - 1U) != ClassId;
     };

diff  --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h
index 182c22752e9ae..a3684c9d45864 100644
--- a/compiler-rt/lib/scudo/standalone/primary64.h
+++ b/compiler-rt/lib/scudo/standalone/primary64.h
@@ -728,6 +728,9 @@ template <typename Config> class SizeClassAllocator64 {
       Context.markFreeBlocks(BG.Batches, DecompactPtr, Region->RegionBeg);
     }
 
+    if (!Context.hasBlockMarked())
+      return 0;
+
     auto SkipRegion = [](UNUSED uptr RegionIndex) { return false; };
     releaseFreeMemoryToOS(Context, Recorder, SkipRegion);
 

diff  --git a/compiler-rt/lib/scudo/standalone/release.h b/compiler-rt/lib/scudo/standalone/release.h
index 12cc8d2c7173b..ef5f23208dff4 100644
--- a/compiler-rt/lib/scudo/standalone/release.h
+++ b/compiler-rt/lib/scudo/standalone/release.h
@@ -258,7 +258,16 @@ struct PageReleaseContext {
     PageSizeLog = getLog2(PageSize);
     RoundedRegionSize = PagesCount << PageSizeLog;
     RoundedSize = NumberOfRegions * RoundedRegionSize;
+  }
+
+  // PageMap is lazily allocated when markFreeBlocks() is invoked.
+  bool hasBlockMarked() const {
+    return PageMap.isAllocated();
+  }
 
+  void ensurePageMapAllocated() {
+    if (PageMap.isAllocated())
+      return;
     PageMap.reset(NumberOfRegions, PagesCount, FullPagesBlockCountMax);
     DCHECK(PageMap.isAllocated());
   }
@@ -266,6 +275,8 @@ struct PageReleaseContext {
   template<class TransferBatchT, typename DecompactPtrT>
   void markFreeBlocks(const IntrusiveList<TransferBatchT> &FreeList,
                       DecompactPtrT DecompactPtr, uptr Base) {
+    ensurePageMapAllocated();
+
     // Iterate over free chunks and count how many free chunks affect each
     // allocated page.
     if (BlockSize <= PageSize && PageSize % BlockSize == 0) {

diff  --git a/compiler-rt/lib/scudo/standalone/tests/release_test.cpp b/compiler-rt/lib/scudo/standalone/tests/release_test.cpp
index 0c3c043d1e087..8625e7fb4b767 100644
--- a/compiler-rt/lib/scudo/standalone/tests/release_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/release_test.cpp
@@ -199,7 +199,9 @@ template <class SizeClassMap> void testReleaseFreeMemoryToOS() {
     scudo::PageReleaseContext Context(BlockSize,
                                       /*RegionSize=*/MaxBlocks * BlockSize,
                                       /*NumberOfRegions=*/1U);
+    ASSERT_FALSE(Context.hasBlockMarked());
     Context.markFreeBlocks(FreeList, DecompactPtr, Recorder.getBase());
+    ASSERT_TRUE(Context.hasBlockMarked());
     releaseFreeMemoryToOS(Context, Recorder, SkipRegion);
     scudo::RegionPageMap &PageMap = Context.PageMap;
 


        


More information about the llvm-commits mailing list