[llvm-branch-commits] [compiler-rt] 6dfe580 - scudo: Move the configuration for the primary allocator to Config. NFCI.
Peter Collingbourne via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 22 14:58:48 PST 2020
Author: Peter Collingbourne
Date: 2020-12-22T14:54:40-08:00
New Revision: 6dfe5801e01d259d00198147b27438ffea39e59f
URL: https://github.com/llvm/llvm-project/commit/6dfe5801e01d259d00198147b27438ffea39e59f
DIFF: https://github.com/llvm/llvm-project/commit/6dfe5801e01d259d00198147b27438ffea39e59f.diff
LOG: scudo: Move the configuration for the primary allocator to Config. NFCI.
This will allow the primary and secondary allocators to share
the MaySupportMemoryTagging bool.
Differential Revision: https://reviews.llvm.org/D93728
Added:
Modified:
compiler-rt/lib/scudo/standalone/allocator_config.h
compiler-rt/lib/scudo/standalone/memtag.h
compiler-rt/lib/scudo/standalone/primary32.h
compiler-rt/lib/scudo/standalone/primary64.h
compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
compiler-rt/lib/scudo/standalone/tests/primary_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/scudo/standalone/allocator_config.h b/compiler-rt/lib/scudo/standalone/allocator_config.h
index 8f1757dab322..12daaa2f6b44 100644
--- a/compiler-rt/lib/scudo/standalone/allocator_config.h
+++ b/compiler-rt/lib/scudo/standalone/allocator_config.h
@@ -25,13 +25,18 @@ namespace scudo {
struct DefaultConfig {
using SizeClassMap = DefaultSizeClassMap;
+ static const bool MaySupportMemoryTagging = false;
+
#if SCUDO_CAN_USE_PRIMARY64
- // 1GB Regions
- typedef SizeClassAllocator64<SizeClassMap, 30U> Primary;
+ typedef SizeClassAllocator64<DefaultConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 30U;
#else
- // 512KB regions
- typedef SizeClassAllocator32<SizeClassMap, 19U> Primary;
+ typedef SizeClassAllocator32<DefaultConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 19U;
#endif
+ static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+
typedef MapAllocatorCache<DefaultConfig> SecondaryCache;
static const u32 SecondaryCacheEntriesArraySize = 32U;
static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U;
@@ -44,15 +49,18 @@ struct DefaultConfig {
struct AndroidConfig {
using SizeClassMap = AndroidSizeClassMap;
+ static const bool MaySupportMemoryTagging = true;
+
#if SCUDO_CAN_USE_PRIMARY64
- // 256MB regions
- typedef SizeClassAllocator64<SizeClassMap, 28U, 1000, 1000,
- /*MaySupportMemoryTagging=*/true>
- Primary;
+ typedef SizeClassAllocator64<AndroidConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 28U;
#else
- // 256KB regions
- typedef SizeClassAllocator32<SizeClassMap, 18U, 1000, 1000> Primary;
+ typedef SizeClassAllocator32<AndroidConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 18U;
#endif
+ static const s32 PrimaryMinReleaseToOsIntervalMs = 1000;
+ static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000;
+
typedef MapAllocatorCache<AndroidConfig> SecondaryCache;
static const u32 SecondaryCacheEntriesArraySize = 256U;
static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U;
@@ -66,13 +74,18 @@ struct AndroidConfig {
struct AndroidSvelteConfig {
using SizeClassMap = SvelteSizeClassMap;
+ static const bool MaySupportMemoryTagging = false;
+
#if SCUDO_CAN_USE_PRIMARY64
- // 128MB regions
- typedef SizeClassAllocator64<SizeClassMap, 27U, 1000, 1000> Primary;
+ typedef SizeClassAllocator64<AndroidSvelteConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 27U;
#else
- // 64KB regions
- typedef SizeClassAllocator32<SizeClassMap, 16U, 1000, 1000> Primary;
+ typedef SizeClassAllocator32<AndroidSvelteConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 16U;
#endif
+ static const s32 PrimaryMinReleaseToOsIntervalMs = 1000;
+ static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000;
+
typedef MapAllocatorCache<AndroidSvelteConfig> SecondaryCache;
static const u32 SecondaryCacheEntriesArraySize = 16U;
static const u32 SecondaryCacheDefaultMaxEntriesCount = 4U;
@@ -86,8 +99,14 @@ struct AndroidSvelteConfig {
#if SCUDO_CAN_USE_PRIMARY64
struct FuchsiaConfig {
- // 1GB Regions
- typedef SizeClassAllocator64<DefaultSizeClassMap, 30U> Primary;
+ using SizeClassMap = DefaultSizeClassMap;
+ static const bool MaySupportMemoryTagging = false;
+
+ typedef SizeClassAllocator64<FuchsiaConfig> Primary;
+ static const uptr PrimaryRegionSizeLog = 30U;
+ static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+
typedef MapAllocatorNoCache SecondaryCache;
template <class A>
using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs.
diff --git a/compiler-rt/lib/scudo/standalone/memtag.h b/compiler-rt/lib/scudo/standalone/memtag.h
index c3c4f574b4fc..d848e3a0b6c9 100644
--- a/compiler-rt/lib/scudo/standalone/memtag.h
+++ b/compiler-rt/lib/scudo/standalone/memtag.h
@@ -268,6 +268,11 @@ inline void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask,
*TaggedEnd = storeTags(*TaggedBegin, *TaggedBegin + Size);
}
+template <typename Config>
+inline constexpr bool allocatorSupportsMemoryTagging() {
+ return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging;
+}
+
} // namespace scudo
#endif
diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h
index 0db95d2e1f11..c744670b4392 100644
--- a/compiler-rt/lib/scudo/standalone/primary32.h
+++ b/compiler-rt/lib/scudo/standalone/primary32.h
@@ -39,20 +39,15 @@ namespace scudo {
// Memory used by this allocator is never unmapped but can be partially
// reclaimed if the platform allows for it.
-template <class SizeClassMapT, uptr RegionSizeLog,
- s32 MinReleaseToOsIntervalMs = INT32_MIN,
- s32 MaxReleaseToOsIntervalMs = INT32_MAX>
-class SizeClassAllocator32 {
+template <typename Config> class SizeClassAllocator32 {
public:
- typedef SizeClassMapT SizeClassMap;
+ typedef typename Config::SizeClassMap SizeClassMap;
// The bytemap can only track UINT8_MAX - 1 classes.
static_assert(SizeClassMap::LargestClassId <= (UINT8_MAX - 1), "");
// Regions should be large enough to hold the largest Block.
- static_assert((1UL << RegionSizeLog) >= SizeClassMap::MaxSize, "");
- typedef SizeClassAllocator32<SizeClassMapT, RegionSizeLog,
- MinReleaseToOsIntervalMs,
- MaxReleaseToOsIntervalMs>
- ThisT;
+ static_assert((1UL << Config::PrimaryRegionSizeLog) >= SizeClassMap::MaxSize,
+ "");
+ typedef SizeClassAllocator32<Config> ThisT;
typedef SizeClassAllocatorLocalCache<ThisT> CacheT;
typedef typename CacheT::TransferBatch TransferBatch;
static const bool SupportsMemoryTagging = false;
@@ -199,9 +194,9 @@ class SizeClassAllocator32 {
bool setOption(Option O, sptr Value) {
if (O == Option::ReleaseInterval) {
- const s32 Interval =
- Max(Min(static_cast<s32>(Value), MaxReleaseToOsIntervalMs),
- MinReleaseToOsIntervalMs);
+ const s32 Interval = Max(
+ Min(static_cast<s32>(Value), Config::PrimaryMaxReleaseToOsIntervalMs),
+ Config::PrimaryMinReleaseToOsIntervalMs);
atomic_store_relaxed(&ReleaseToOsIntervalMs, Interval);
return true;
}
@@ -236,8 +231,9 @@ class SizeClassAllocator32 {
private:
static const uptr NumClasses = SizeClassMap::NumClasses;
- static const uptr RegionSize = 1UL << RegionSizeLog;
- static const uptr NumRegions = SCUDO_MMAP_RANGE_SIZE >> RegionSizeLog;
+ static const uptr RegionSize = 1UL << Config::PrimaryRegionSizeLog;
+ static const uptr NumRegions =
+ SCUDO_MMAP_RANGE_SIZE >> Config::PrimaryRegionSizeLog;
static const u32 MaxNumBatches = SCUDO_ANDROID ? 4U : 8U;
typedef FlatByteMap<NumRegions> ByteMap;
@@ -270,7 +266,7 @@ class SizeClassAllocator32 {
static_assert(sizeof(SizeClassInfo) % SCUDO_CACHE_LINE_SIZE == 0, "");
uptr computeRegionId(uptr Mem) {
- const uptr Id = Mem >> RegionSizeLog;
+ const uptr Id = Mem >> Config::PrimaryRegionSizeLog;
CHECK_LT(Id, NumRegions);
return Id;
}
diff --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h
index f9854cbfd4d6..df1310aa8e95 100644
--- a/compiler-rt/lib/scudo/standalone/primary64.h
+++ b/compiler-rt/lib/scudo/standalone/primary64.h
@@ -40,21 +40,14 @@ namespace scudo {
// The memory used by this allocator is never unmapped, but can be partially
// released if the platform allows for it.
-template <class SizeClassMapT, uptr RegionSizeLog,
- s32 MinReleaseToOsIntervalMs = INT32_MIN,
- s32 MaxReleaseToOsIntervalMs = INT32_MAX,
- bool MaySupportMemoryTagging = false>
-class SizeClassAllocator64 {
+template <typename Config> class SizeClassAllocator64 {
public:
- typedef SizeClassMapT SizeClassMap;
- typedef SizeClassAllocator64<
- SizeClassMap, RegionSizeLog, MinReleaseToOsIntervalMs,
- MaxReleaseToOsIntervalMs, MaySupportMemoryTagging>
- ThisT;
+ typedef typename Config::SizeClassMap SizeClassMap;
+ typedef SizeClassAllocator64<Config> ThisT;
typedef SizeClassAllocatorLocalCache<ThisT> CacheT;
typedef typename CacheT::TransferBatch TransferBatch;
static const bool SupportsMemoryTagging =
- MaySupportMemoryTagging && archSupportsMemoryTagging();
+ allocatorSupportsMemoryTagging<Config>();
static uptr getSizeByClassId(uptr ClassId) {
return (ClassId == SizeClassMap::BatchClassId)
@@ -178,9 +171,9 @@ class SizeClassAllocator64 {
bool setOption(Option O, sptr Value) {
if (O == Option::ReleaseInterval) {
- const s32 Interval =
- Max(Min(static_cast<s32>(Value), MaxReleaseToOsIntervalMs),
- MinReleaseToOsIntervalMs);
+ const s32 Interval = Max(
+ Min(static_cast<s32>(Value), Config::PrimaryMaxReleaseToOsIntervalMs),
+ Config::PrimaryMinReleaseToOsIntervalMs);
atomic_store_relaxed(&ReleaseToOsIntervalMs, Interval);
return true;
}
@@ -258,7 +251,7 @@ class SizeClassAllocator64 {
AtomicOptions Options;
private:
- static const uptr RegionSize = 1UL << RegionSizeLog;
+ static const uptr RegionSize = 1UL << Config::PrimaryRegionSizeLog;
static const uptr NumClasses = SizeClassMap::NumClasses;
static const uptr PrimarySize = RegionSize * NumClasses;
@@ -308,7 +301,7 @@ class SizeClassAllocator64 {
}
uptr getRegionBaseByClassId(uptr ClassId) const {
- return PrimaryBase + (ClassId << RegionSizeLog);
+ return PrimaryBase + (ClassId << Config::PrimaryRegionSizeLog);
}
NOINLINE TransferBatch *populateFreeList(CacheT *C, uptr ClassId,
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index b0ab0244e877..53874933e7ac 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -401,10 +401,15 @@ struct DeathSizeClassConfig {
static const scudo::uptr DeathRegionSizeLog = 20U;
struct DeathConfig {
+ static const bool MaySupportMemoryTagging = false;
+
// Tiny allocator, its Primary only serves chunks of four sizes.
- using DeathSizeClassMap = scudo::FixedSizeClassMap<DeathSizeClassConfig>;
- typedef scudo::SizeClassAllocator64<DeathSizeClassMap, DeathRegionSizeLog>
- Primary;
+ using SizeClassMap = scudo::FixedSizeClassMap<DeathSizeClassConfig>;
+ typedef scudo::SizeClassAllocator64<DeathConfig> Primary;
+ static const scudo::uptr PrimaryRegionSizeLog = DeathRegionSizeLog;
+ static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const scudo::s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+
typedef scudo::MapAllocatorNoCache SecondaryCache;
template <class A> using TSDRegistryT = scudo::TSDRegistrySharedT<A, 1U, 1U>;
};
@@ -460,13 +465,13 @@ TEST(ScudoCombinedTest, FullRegion) {
std::vector<void *> V;
scudo::uptr FailedAllocationsCount = 0;
for (scudo::uptr ClassId = 1U;
- ClassId <= DeathConfig::DeathSizeClassMap::LargestClassId; ClassId++) {
+ ClassId <= DeathConfig::SizeClassMap::LargestClassId; ClassId++) {
const scudo::uptr Size =
- DeathConfig::DeathSizeClassMap::getSizeByClassId(ClassId);
+ DeathConfig::SizeClassMap::getSizeByClassId(ClassId);
// Allocate enough to fill all of the regions above this one.
const scudo::uptr MaxNumberOfChunks =
((1U << DeathRegionSizeLog) / Size) *
- (DeathConfig::DeathSizeClassMap::LargestClassId - ClassId + 1);
+ (DeathConfig::SizeClassMap::LargestClassId - ClassId + 1);
void *P;
for (scudo::uptr I = 0; I <= MaxNumberOfChunks; I++) {
P = Allocator->allocate(Size - 64U, Origin);
diff --git a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp
index 67d1fe52acef..eed64314cc3d 100644
--- a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp
@@ -52,20 +52,51 @@ template <typename Primary> static void testPrimary() {
Str.output();
}
+template <typename SizeClassMapT> struct TestConfig1 {
+ using SizeClassMap = SizeClassMapT;
+ static const scudo::uptr PrimaryRegionSizeLog = 18U;
+ static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const scudo::s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+ static const bool MaySupportMemoryTagging = false;
+};
+
+template <typename SizeClassMapT> struct TestConfig2 {
+ using SizeClassMap = SizeClassMapT;
+ static const scudo::uptr PrimaryRegionSizeLog = 24U;
+ static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const scudo::s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+ static const bool MaySupportMemoryTagging = false;
+};
+
+template <typename SizeClassMapT> struct TestConfig3 {
+ using SizeClassMap = SizeClassMapT;
+ static const scudo::uptr PrimaryRegionSizeLog = 24U;
+ static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const scudo::s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+ static const bool MaySupportMemoryTagging = true;
+};
+
TEST(ScudoPrimaryTest, BasicPrimary) {
using SizeClassMap = scudo::DefaultSizeClassMap;
#if !SCUDO_FUCHSIA
- testPrimary<scudo::SizeClassAllocator32<SizeClassMap, 18U>>();
+ testPrimary<scudo::SizeClassAllocator32<TestConfig1<SizeClassMap>>>();
#endif
- testPrimary<scudo::SizeClassAllocator64<SizeClassMap, 24U>>();
- testPrimary<scudo::SizeClassAllocator64<SizeClassMap, 24U, INT32_MIN,
- INT32_MAX, true>>();
+ testPrimary<scudo::SizeClassAllocator64<TestConfig2<SizeClassMap>>>();
+ testPrimary<scudo::SizeClassAllocator64<TestConfig3<SizeClassMap>>>();
}
+struct SmallRegionsConfig {
+ using SizeClassMap = scudo::DefaultSizeClassMap;
+ static const scudo::uptr PrimaryRegionSizeLog = 20U;
+ static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
+ static const scudo::s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
+ static const bool MaySupportMemoryTagging = false;
+};
+
// The 64-bit SizeClassAllocator can be easily OOM'd with small region sizes.
// For the 32-bit one, it requires actually exhausting memory, so we skip it.
TEST(ScudoPrimaryTest, Primary64OOM) {
- using Primary = scudo::SizeClassAllocator64<scudo::DefaultSizeClassMap, 20U>;
+ using Primary = scudo::SizeClassAllocator64<SmallRegionsConfig>;
using TransferBatch = Primary::CacheT::TransferBatch;
Primary Allocator;
Allocator.init(/*ReleaseToOsInterval=*/-1);
@@ -142,11 +173,10 @@ template <typename Primary> static void testIteratePrimary() {
TEST(ScudoPrimaryTest, PrimaryIterate) {
using SizeClassMap = scudo::DefaultSizeClassMap;
#if !SCUDO_FUCHSIA
- testIteratePrimary<scudo::SizeClassAllocator32<SizeClassMap, 18U>>();
+ testIteratePrimary<scudo::SizeClassAllocator32<TestConfig1<SizeClassMap>>>();
#endif
- testIteratePrimary<scudo::SizeClassAllocator64<SizeClassMap, 24U>>();
- testIteratePrimary<scudo::SizeClassAllocator64<SizeClassMap, 24U, INT32_MIN,
- INT32_MAX, true>>();
+ testIteratePrimary<scudo::SizeClassAllocator64<TestConfig2<SizeClassMap>>>();
+ testIteratePrimary<scudo::SizeClassAllocator64<TestConfig3<SizeClassMap>>>();
}
static std::mutex Mutex;
@@ -204,11 +234,10 @@ template <typename Primary> static void testPrimaryThreaded() {
TEST(ScudoPrimaryTest, PrimaryThreaded) {
using SizeClassMap = scudo::SvelteSizeClassMap;
#if !SCUDO_FUCHSIA
- testPrimaryThreaded<scudo::SizeClassAllocator32<SizeClassMap, 18U>>();
+ testPrimaryThreaded<scudo::SizeClassAllocator32<TestConfig1<SizeClassMap>>>();
#endif
- testPrimaryThreaded<scudo::SizeClassAllocator64<SizeClassMap, 24U>>();
- testPrimaryThreaded<scudo::SizeClassAllocator64<SizeClassMap, 24U, INT32_MIN,
- INT32_MAX, true>>();
+ testPrimaryThreaded<scudo::SizeClassAllocator64<TestConfig2<SizeClassMap>>>();
+ testPrimaryThreaded<scudo::SizeClassAllocator64<TestConfig3<SizeClassMap>>>();
}
// Through a simple allocation that spans two pages, verify that releaseToOS
@@ -236,9 +265,8 @@ template <typename Primary> static void testReleaseToOS() {
TEST(ScudoPrimaryTest, ReleaseToOS) {
using SizeClassMap = scudo::DefaultSizeClassMap;
#if !SCUDO_FUCHSIA
- testReleaseToOS<scudo::SizeClassAllocator32<SizeClassMap, 18U>>();
+ testReleaseToOS<scudo::SizeClassAllocator32<TestConfig1<SizeClassMap>>>();
#endif
- testReleaseToOS<scudo::SizeClassAllocator64<SizeClassMap, 24U>>();
- testReleaseToOS<scudo::SizeClassAllocator64<SizeClassMap, 24U, INT32_MIN,
- INT32_MAX, true>>();
+ testReleaseToOS<scudo::SizeClassAllocator64<TestConfig2<SizeClassMap>>>();
+ testReleaseToOS<scudo::SizeClassAllocator64<TestConfig3<SizeClassMap>>>();
}
More information about the llvm-branch-commits
mailing list