[compiler-rt] [scudo] Dumping allocator config when printStats() (PR #192489)

Sadaf Ebrahimi via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 16 09:56:05 PDT 2026


https://github.com/sadafebrahimi created https://github.com/llvm/llvm-project/pull/192489

So far printStats() dumps partial information of the allocator config. Given that user is able to have custom config, we want to dump all the configurations to reduce variances while reviewing the stats.

>From 891b64e3931712ae9fce8656a41d476859984408 Mon Sep 17 00:00:00 2001
From: Sadaf Ebrahimi <sadafebrahimi at google.com>
Date: Thu, 16 Apr 2026 16:55:05 +0000
Subject: [PATCH] [scudo] Dumping allocator config when printStats()

So far printStats() dumps partial information of the allocator config.
Given that user is able to have custom config, we want to dump all the
configurations to reduce variances while reviewing the stats.
---
 .../standalone/allocator_config_wrapper.h     |  26 +++++
 compiler-rt/lib/scudo/standalone/combined.h   |   1 +
 compiler-rt/lib/scudo/standalone/primary32.h  |   1 +
 compiler-rt/lib/scudo/standalone/primary64.h  |   1 +
 compiler-rt/lib/scudo/standalone/secondary.h  |   2 +
 .../scudo/standalone/tests/combined_test.cpp  | 102 ++++++++++++++++++
 6 files changed, 133 insertions(+)

diff --git a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
index 5bfa700c2f8d8..038328e411bd6 100644
--- a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
+++ b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
@@ -51,6 +51,14 @@ template <typename AllocatorConfig> struct BaseConfig {
   }
 
 #include "allocator_config.def"
+
+  static void getConfigValues(ScopedString *Str) {
+    Str->append("Config Stats Combined: MaySupportMemoryTagging: %s; "
+                "QuarantineDisabled: %s; ExactUsableSize: %s\n",
+                getMaySupportMemoryTagging() ? "true" : "false",
+                getQuarantineDisabled() ? "true" : "false",
+                getExactUsableSize() ? "true" : "false");
+  }
 }; // BaseConfig
 
 template <typename AllocatorConfig> struct PrimaryConfig {
@@ -87,6 +95,16 @@ template <typename AllocatorConfig> struct PrimaryConfig {
 
 #include "allocator_config.def"
 
+  static void getConfigValues(ScopedString *Str) {
+    Str->append("Config Stats Primary: RegionSizeLog: %zu; GroupSizeLog: %zu; "
+                "EnableBlockCache: %s; CompactPtrScale: "
+                "%zu; EnableRandomOffset: %s; EnableContiguousRegions: %s\n",
+                getRegionSizeLog(), getGroupSizeLog(),
+                getEnableBlockCache() ? "true" : "false", getCompactPtrScale(),
+                getEnableRandomOffset() ? "true" : "false",
+                getEnableContiguousRegions() ? "true" : "false");
+  }
+
 }; // PrimaryConfig
 
 template <typename AllocatorConfig> struct SecondaryConfig {
@@ -129,6 +147,14 @@ template <typename AllocatorConfig> struct SecondaryConfig {
     return NAME##State<typename AllocatorConfig::Secondary>::getValue();       \
   }
 #include "allocator_config.def"
+    static void getConfigValues(ScopedString *Str) {
+      Str->append("Config Stats Secondary: EntriesArraySize: %" PRIu32
+                  "; QuarantineSize: %" PRIu32
+                  "; DefaultMaxEntriesCount: %" PRIu32
+                  "; DefaultMaxEntrySize: %zu\n",
+                  getEntriesArraySize(), getQuarantineSize(),
+                  getDefaultMaxEntriesCount(), getDefaultMaxEntrySize());
+    }
   }; // CacheConfig
 };   // SecondaryConfig
 
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index 1c1a92aefd461..6f85e12616f9e 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -1775,6 +1775,7 @@ class Allocator {
   }
 
   uptr getStats(ScopedString *Str) {
+    AllocatorConfig::getConfigValues(Str);
     Primary.getStats(Str);
     Secondary.getStats(Str);
     if (!AllocatorConfig::getQuarantineDisabled())
diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h
index 037fa3d7a7dcb..37b84aeb78c55 100644
--- a/compiler-rt/lib/scudo/standalone/primary32.h
+++ b/compiler-rt/lib/scudo/standalone/primary32.h
@@ -454,6 +454,7 @@ void SizeClassAllocator32<Config>::iterateOverBlocks(F Callback) {
 template <typename Config>
 void SizeClassAllocator32<Config>::getStats(ScopedString *Str) {
   // TODO(kostyak): get the RSS per region.
+  Config::getConfigValues(Str);
   uptr TotalMapped = 0;
   uptr PoppedBlocks = 0;
   uptr PushedBlocks = 0;
diff --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h
index a185d497e4963..0c18a59ef34d8 100644
--- a/compiler-rt/lib/scudo/standalone/primary64.h
+++ b/compiler-rt/lib/scudo/standalone/primary64.h
@@ -1102,6 +1102,7 @@ void SizeClassAllocator64<Config>::iterateOverBlocks(F Callback) {
 template <typename Config>
 void SizeClassAllocator64<Config>::getStats(ScopedString *Str) {
   // TODO(kostyak): get the RSS per region.
+  Config::getConfigValues(Str);
   uptr TotalMapped = 0;
   uptr PoppedBlocks = 0;
   uptr PushedBlocks = 0;
diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h
index a740836a144c5..67319c4c72c67 100644
--- a/compiler-rt/lib/scudo/standalone/secondary.h
+++ b/compiler-rt/lib/scudo/standalone/secondary.h
@@ -214,6 +214,7 @@ class MapAllocatorCache {
 public:
   void getStats(ScopedString *Str) {
     ScopedLock L(Mutex);
+    Config::getConfigValues(Str);
     uptr Integral;
     uptr Fractional;
     computePercentage(SuccessfulRetrieves, CallsToRetrieve, &Integral,
@@ -955,6 +956,7 @@ void MapAllocator<Config>::deallocate(const Options &Options, void *Ptr)
 template <typename Config>
 void MapAllocator<Config>::getStats(ScopedString *Str) EXCLUDES(Mutex) {
   ScopedLock L(Mutex);
+
   Str->append("Stats: MapAllocator: allocated %u times (%zuK), freed %u times "
               "(%zuK), remains %u (%zuK) max %zuM, Fragmented %zuK\n",
               NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees,
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index 6a34e8be11151..b921873dcddbe 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -1893,3 +1893,105 @@ TEST(ScudoCombinedTest, VerifyConfigOverrideMatchChecks) {
     Allocator->deallocateAligned(Ptr, scudo::Chunk::Origin::Malloc, Alignment);
   }
 }
+
+struct TestAllBoolFalseConfig {
+  static const bool MaySupportMemoryTagging = false;
+  static const bool QuarantineDisabled = false;
+  static const bool ExactUsableSize = false;
+  template <class A> using TSDRegistryT = scudo::TSDRegistrySharedT<A, 8U, 4U>;
+
+  struct Primary {
+    using SizeClassMap = scudo::AndroidSizeClassMap;
+    static const scudo::uptr RegionSizeLog = 18U;
+    static const scudo::uptr GroupSizeLog = 18U;
+#if SCUDO_CAN_USE_PRIMARY64
+    static const scudo::uptr MapSizeIncrement = 1UL << 18;
+#endif
+    static const bool EnableBlockCache = false;
+    static const scudo::uptr CompactPtrScale = 0;
+    static const bool EnableRandomOffset = false;
+    static const bool EnableContiguousRegions = false;
+  };
+
+#if SCUDO_CAN_USE_PRIMARY64
+  template <typename Config>
+  using PrimaryT = scudo::SizeClassAllocator64<Config>;
+#else
+  template <typename Config>
+  using PrimaryT = scudo::SizeClassAllocator32<Config>;
+#endif
+
+  struct Secondary {
+    template <typename Config>
+    using CacheT = scudo::MapAllocatorNoCache<Config>;
+  };
+  template <typename Config> using SecondaryT = scudo::MapAllocator<Config>;
+};
+
+TEST(ScudoCombinedTest, VerifyAllBoolFalseConfig) {
+  using AllocatorT = scudo::Allocator<TestAllBoolFalseConfig>;
+  auto Allocator = std::unique_ptr<AllocatorT>(new AllocatorT());
+
+  std::string Stats(10000, '\0');
+  Allocator->getStats(Stats.data(), Stats.size());
+  EXPECT_NE(Stats.find("MaySupportMemoryTagging: false"), std::string::npos);
+  EXPECT_NE(Stats.find("QuarantineDisabled: false"), std::string::npos);
+  EXPECT_NE(Stats.find("ExactUsableSize: false"), std::string::npos);
+  EXPECT_NE(Stats.find("RegionSizeLog: 18"), std::string::npos);
+  EXPECT_NE(Stats.find("GroupSizeLog: 18"), std::string::npos);
+  EXPECT_NE(Stats.find("EnableBlockCache: false"), std::string::npos);
+  EXPECT_NE(Stats.find("CompactPtrScale: 0"), std::string::npos);
+  EXPECT_NE(Stats.find("EnableRandomOffset: false"), std::string::npos);
+  EXPECT_NE(Stats.find("EnableContiguousRegions: false"), std::string::npos);
+}
+
+struct TestAllBoolTrueConfig {
+  static const bool MaySupportMemoryTagging = true;
+  static const bool QuarantineDisabled = true;
+  static const bool ExactUsableSize = true;
+  template <class A> using TSDRegistryT = scudo::TSDRegistrySharedT<A, 8U, 4U>;
+
+  struct Primary {
+    using SizeClassMap = scudo::AndroidSizeClassMap;
+    static const scudo::uptr RegionSizeLog = 18U;
+    static const scudo::uptr GroupSizeLog = 18U;
+#if SCUDO_CAN_USE_PRIMARY64
+    static const scudo::uptr MapSizeIncrement = 1UL << 18;
+#endif
+    static const bool EnableBlockCache = true;
+    static const scudo::uptr CompactPtrScale = 0;
+    static const bool EnableRandomOffset = true;
+    static const bool EnableContiguousRegions = true;
+  };
+
+#if SCUDO_CAN_USE_PRIMARY64
+  template <typename Config>
+  using PrimaryT = scudo::SizeClassAllocator64<Config>;
+#else
+  template <typename Config>
+  using PrimaryT = scudo::SizeClassAllocator32<Config>;
+#endif
+
+  struct Secondary {
+    template <typename Config>
+    using CacheT = scudo::MapAllocatorNoCache<Config>;
+  };
+  template <typename Config> using SecondaryT = scudo::MapAllocator<Config>;
+};
+
+TEST(ScudoCombinedTest, VerifyAllBoolTrueConfig) {
+  using AllocatorT = scudo::Allocator<TestAllBoolTrueConfig>;
+  auto Allocator = std::unique_ptr<AllocatorT>(new AllocatorT());
+
+  std::string Stats(10000, '\0');
+  Allocator->getStats(Stats.data(), Stats.size());
+  EXPECT_NE(Stats.find("MaySupportMemoryTagging: true"), std::string::npos);
+  EXPECT_NE(Stats.find("QuarantineDisabled: true"), std::string::npos);
+  EXPECT_NE(Stats.find("ExactUsableSize: true"), std::string::npos);
+  EXPECT_NE(Stats.find("RegionSizeLog: 18"), std::string::npos);
+  EXPECT_NE(Stats.find("GroupSizeLog: 18"), std::string::npos);
+  EXPECT_NE(Stats.find("EnableBlockCache: true"), std::string::npos);
+  EXPECT_NE(Stats.find("CompactPtrScale: 0"), std::string::npos);
+  EXPECT_NE(Stats.find("EnableRandomOffset: true"), std::string::npos);
+  EXPECT_NE(Stats.find("EnableContiguousRegions: true"), std::string::npos);
+}
\ No newline at end of file



More information about the llvm-commits mailing list