[compiler-rt] [scudo] Dumping allocator config when printStats() (PR #192489)
Sadaf Ebrahimi via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 09:51:22 PDT 2026
https://github.com/sadafebrahimi updated https://github.com/llvm/llvm-project/pull/192489
>From 23991577c90bab2136b3ddab509d48500a1053a9 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 | 42 +++++++-
compiler-rt/lib/scudo/standalone/combined.h | 2 +
compiler-rt/lib/scudo/standalone/primary32.h | 2 +
compiler-rt/lib/scudo/standalone/primary64.h | 2 +
compiler-rt/lib/scudo/standalone/secondary.h | 2 +
.../scudo/standalone/tests/combined_test.cpp | 98 +++++++++++++++++++
6 files changed, 147 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
index 5bfa700c2f8d8..dfe14bb754046 100644
--- a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
+++ b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
@@ -51,6 +51,16 @@ template <typename AllocatorConfig> struct BaseConfig {
}
#include "allocator_config.def"
+
+ static void getConfigValues(ScopedString *Str) {
+#define BASE_OPTIONAL(TYPE, NAME, DEFAULT) \
+ Str->append(#NAME); \
+ Str->append(": "); \
+ Str->append(get##NAME()); \
+ Str->append("; ");
+#include "allocator_config.def"
+ }
+
}; // BaseConfig
template <typename AllocatorConfig> struct PrimaryConfig {
@@ -87,6 +97,15 @@ template <typename AllocatorConfig> struct PrimaryConfig {
#include "allocator_config.def"
+ static void getConfigValues(ScopedString *Str) {
+#define PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT) \
+ Str->append(#NAME); \
+ Str->append(": "); \
+ Str->append(get##NAME()); \
+ Str->append("; ");
+#include "allocator_config.def"
+ }
+
}; // PrimaryConfig
template <typename AllocatorConfig> struct SecondaryConfig {
@@ -129,8 +148,29 @@ template <typename AllocatorConfig> struct SecondaryConfig {
return NAME##State<typename AllocatorConfig::Secondary>::getValue(); \
}
#include "allocator_config.def"
+
+ static void getConfigValues(ScopedString *Str) {
+#define SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT) \
+ Str->append(#NAME); \
+ Str->append(": "); \
+ Str->append(get##NAME()); \
+ Str->append("; ");
+#include "allocator_config.def"
+ }
+
}; // CacheConfig
-}; // SecondaryConfig
+
+ static void getConfigValues(ScopedString *Str) {
+#define SECONDARY_OPTIONAL(TYPE, NAME, DEFAULT) \
+ Str->append(#NAME); \
+ Str->append(": "); \
+ Str->append(get##NAME()); \
+ Str->append("; ");
+#include "allocator_config.def"
+ Str->append("\nConfig Stats Secondary Cache: ");
+ CacheConfig::getConfigValues(Str);
+ }
+}; // SecondaryConfig
#undef OPTIONAL_TEMPLATE
#undef OPTIONAL_TEMPLATE_TYPE
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index 1c1a92aefd461..72b4b361475b2 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -1775,6 +1775,8 @@ class Allocator {
}
uptr getStats(ScopedString *Str) {
+ Str->append("Config Stats Base: ");
+ 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..5720c9f308dac 100644
--- a/compiler-rt/lib/scudo/standalone/primary32.h
+++ b/compiler-rt/lib/scudo/standalone/primary32.h
@@ -454,6 +454,8 @@ void SizeClassAllocator32<Config>::iterateOverBlocks(F Callback) {
template <typename Config>
void SizeClassAllocator32<Config>::getStats(ScopedString *Str) {
// TODO(kostyak): get the RSS per region.
+ Str->append("\nConfig Stats Primary32: ");
+ 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..6ee56d6c99291 100644
--- a/compiler-rt/lib/scudo/standalone/primary64.h
+++ b/compiler-rt/lib/scudo/standalone/primary64.h
@@ -1102,6 +1102,8 @@ void SizeClassAllocator64<Config>::iterateOverBlocks(F Callback) {
template <typename Config>
void SizeClassAllocator64<Config>::getStats(ScopedString *Str) {
// TODO(kostyak): get the RSS per region.
+ Str->append("\nConfig Stats Primary64: ");
+ 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 e782464034bd4..cce8f47eda54c 100644
--- a/compiler-rt/lib/scudo/standalone/secondary.h
+++ b/compiler-rt/lib/scudo/standalone/secondary.h
@@ -217,6 +217,8 @@ class MapAllocatorCache {
public:
void getStats(ScopedString *Str) {
ScopedLock L(Mutex);
+ Str->append("Config Stats Secondary: ");
+ Config::getConfigValues(Str);
uptr Integral;
uptr Fractional;
computePercentage(SuccessfulRetrieves, CallsToRetrieve, &Integral,
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index 6a34e8be11151..1a62463ce5e3c 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -1893,3 +1893,101 @@ 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("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("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);
+}
More information about the llvm-commits
mailing list