[compiler-rt] [scudo] Separated committed and decommitted entries. (PR #101409)

Christopher Ferris via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 31 19:47:38 PDT 2024


================
@@ -335,56 +354,69 @@ template <typename Config> class MapAllocatorCache {
     // 10% of the requested size proved to be the optimal choice for
     // retrieving cached blocks after testing several options.
     constexpr u32 FragmentedBytesDivisor = 10;
-    bool Found = false;
     CachedBlock Entry;
     uptr EntryHeaderPos = 0;
+    uptr OptimalFitIndex = CachedBlock::InvalidEntry;
     {
       ScopedLock L(Mutex);
       CallsToRetrieve++;
       if (EntriesCount == 0)
         return false;
-      u32 OptimalFitIndex = 0;
       uptr MinDiff = UINTPTR_MAX;
-      for (u32 I = LRUHead; I != CachedBlock::InvalidEntry;
-           I = Entries[I].Next) {
-        const uptr CommitBase = Entries[I].CommitBase;
-        const uptr CommitSize = Entries[I].CommitSize;
-        const uptr AllocPos =
-            roundDown(CommitBase + CommitSize - Size, Alignment);
-        const uptr HeaderPos = AllocPos - HeadersSize;
-        if (HeaderPos > CommitBase + CommitSize)
-          continue;
-        if (HeaderPos < CommitBase ||
-            AllocPos > CommitBase + PageSize * MaxUnusedCachePages) {
-          continue;
-        }
-        Found = true;
-        const uptr Diff = HeaderPos - CommitBase;
-        // immediately use a cached block if it's size is close enough to the
-        // requested size.
-        const uptr MaxAllowedFragmentedBytes =
-            (CommitBase + CommitSize - HeaderPos) / FragmentedBytesDivisor;
-        if (Diff <= MaxAllowedFragmentedBytes) {
+      EntryListT OptimalFitListType = NONE;
+      auto FindAvailableEntry = [&](EntryListT ListType) REQUIRES(Mutex) {
+        for (uptr I = EntryLists[ListType].Head; I != CachedBlock::InvalidEntry;
+             I = Entries[I].Next) {
+          const uptr CommitBase = Entries[I].CommitBase;
+          const uptr CommitSize = Entries[I].CommitSize;
+          const uptr AllocPos =
+              roundDown(CommitBase + CommitSize - Size, Alignment);
+          const uptr HeaderPos = AllocPos - HeadersSize;
+          if (HeaderPos > CommitBase + CommitSize)
+            continue;
+          if (HeaderPos < CommitBase ||
+              AllocPos > CommitBase + PageSize * MaxUnusedCachePages)
+            continue;
+
+          const uptr Diff = HeaderPos - CommitBase;
+          // immediately use a cached block if it's size is close enough to
+          // the requested size.
+          const uptr MaxAllowedFragmentedBytes =
+              (CommitBase + CommitSize - HeaderPos) / FragmentedBytesDivisor;
+          if (Diff <= MaxAllowedFragmentedBytes) {
+            OptimalFitIndex = I;
+            EntryHeaderPos = HeaderPos;
+            OptimalFitListType = ListType;
+            return Entries[OptimalFitIndex];
----------------
cferris1000 wrote:

I didn't think about this the first time I saw this code, but I think you could change this to return a boolean, and directly set Entry everywhere you return an entry. This means that the code at the end would look like this:

      if (!FindAvailableEntry(COMMITTED) && !FindAvailableEntry(DECOMMITTED)) 
        return false;

https://github.com/llvm/llvm-project/pull/101409


More information about the llvm-commits mailing list