xref: /llvm-project/compiler-rt/lib/scudo/standalone/tests/allocator_config_test.cpp (revision 2dc9ec47fb16a01c8f7cbb76fba4ad00ac4cb81b)
1*2dc9ec47SChiaHungDuan //===-- allocator_config_test.cpp -------------------------------*- C++ -*-===//
2*2dc9ec47SChiaHungDuan //
3*2dc9ec47SChiaHungDuan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2dc9ec47SChiaHungDuan // See https://llvm.org/LICENSE.txt for license information.
5*2dc9ec47SChiaHungDuan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*2dc9ec47SChiaHungDuan //
7*2dc9ec47SChiaHungDuan //===----------------------------------------------------------------------===//
8*2dc9ec47SChiaHungDuan 
9*2dc9ec47SChiaHungDuan #include "tests/scudo_unit_test.h"
10*2dc9ec47SChiaHungDuan 
11*2dc9ec47SChiaHungDuan #include "allocator_config.h"
12*2dc9ec47SChiaHungDuan #include "allocator_config_wrapper.h"
13*2dc9ec47SChiaHungDuan #include "common.h"
14*2dc9ec47SChiaHungDuan #include "secondary.h"
15*2dc9ec47SChiaHungDuan 
16*2dc9ec47SChiaHungDuan #include <type_traits>
17*2dc9ec47SChiaHungDuan 
18*2dc9ec47SChiaHungDuan struct TestBaseConfig {
19*2dc9ec47SChiaHungDuan   template <typename> using TSDRegistryT = void;
20*2dc9ec47SChiaHungDuan   template <typename> using PrimaryT = void;
21*2dc9ec47SChiaHungDuan   template <typename> using SecondaryT = void;
22*2dc9ec47SChiaHungDuan };
23*2dc9ec47SChiaHungDuan 
24*2dc9ec47SChiaHungDuan struct TestBaseConfigEnableOptionalFlag : public TestBaseConfig {
25*2dc9ec47SChiaHungDuan   static const bool MaySupportMemoryTagging = true;
26*2dc9ec47SChiaHungDuan   // Use the getter to avoid the test to `use` the address of static const
27*2dc9ec47SChiaHungDuan   // variable (which requires additional explicit definition).
getMaySupportMemoryTaggingTestBaseConfigEnableOptionalFlag28*2dc9ec47SChiaHungDuan   static bool getMaySupportMemoryTagging() { return MaySupportMemoryTagging; }
29*2dc9ec47SChiaHungDuan };
30*2dc9ec47SChiaHungDuan 
31*2dc9ec47SChiaHungDuan struct TestBasePrimaryConfig {
32*2dc9ec47SChiaHungDuan   using SizeClassMap = void;
33*2dc9ec47SChiaHungDuan   static const scudo::uptr RegionSizeLog = 18U;
34*2dc9ec47SChiaHungDuan   static const scudo::uptr GroupSizeLog = 18U;
35*2dc9ec47SChiaHungDuan   static const scudo::s32 MinReleaseToOsIntervalMs = INT32_MIN;
36*2dc9ec47SChiaHungDuan   static const scudo::s32 MaxReleaseToOsIntervalMs = INT32_MAX;
37*2dc9ec47SChiaHungDuan   typedef scudo::uptr CompactPtrT;
38*2dc9ec47SChiaHungDuan   static const scudo::uptr CompactPtrScale = 0;
39*2dc9ec47SChiaHungDuan   static const scudo::uptr MapSizeIncrement = 1UL << 18;
40*2dc9ec47SChiaHungDuan };
41*2dc9ec47SChiaHungDuan 
42*2dc9ec47SChiaHungDuan struct TestPrimaryConfig : public TestBaseConfig {
43*2dc9ec47SChiaHungDuan   struct Primary : TestBasePrimaryConfig {};
44*2dc9ec47SChiaHungDuan };
45*2dc9ec47SChiaHungDuan 
46*2dc9ec47SChiaHungDuan struct TestPrimaryConfigEnableOptionalFlag : public TestBaseConfig {
47*2dc9ec47SChiaHungDuan   struct Primary : TestBasePrimaryConfig {
48*2dc9ec47SChiaHungDuan     static const bool EnableRandomOffset = true;
getEnableRandomOffsetTestPrimaryConfigEnableOptionalFlag::Primary49*2dc9ec47SChiaHungDuan     static bool getEnableRandomOffset() { return EnableRandomOffset; }
50*2dc9ec47SChiaHungDuan   };
51*2dc9ec47SChiaHungDuan };
52*2dc9ec47SChiaHungDuan 
53*2dc9ec47SChiaHungDuan struct TestPrimaryConfigEnableOptionalType : public TestBaseConfig {
54*2dc9ec47SChiaHungDuan   struct DummyConditionVariable {};
55*2dc9ec47SChiaHungDuan 
56*2dc9ec47SChiaHungDuan   struct Primary : TestBasePrimaryConfig {
57*2dc9ec47SChiaHungDuan     using ConditionVariableT = DummyConditionVariable;
58*2dc9ec47SChiaHungDuan   };
59*2dc9ec47SChiaHungDuan };
60*2dc9ec47SChiaHungDuan 
61*2dc9ec47SChiaHungDuan struct TestSecondaryConfig : public TestPrimaryConfig {
62*2dc9ec47SChiaHungDuan   struct Secondary {
63*2dc9ec47SChiaHungDuan     template <typename Config>
64*2dc9ec47SChiaHungDuan     using CacheT = scudo::MapAllocatorNoCache<Config>;
65*2dc9ec47SChiaHungDuan   };
66*2dc9ec47SChiaHungDuan };
67*2dc9ec47SChiaHungDuan 
68*2dc9ec47SChiaHungDuan struct TestSecondaryCacheConfigEnableOptionalFlag : public TestPrimaryConfig {
69*2dc9ec47SChiaHungDuan   struct Secondary {
70*2dc9ec47SChiaHungDuan     struct Cache {
71*2dc9ec47SChiaHungDuan       static const scudo::u32 EntriesArraySize = 256U;
getEntriesArraySizeTestSecondaryCacheConfigEnableOptionalFlag::Secondary::Cache72*2dc9ec47SChiaHungDuan       static scudo::u32 getEntriesArraySize() { return EntriesArraySize; }
73*2dc9ec47SChiaHungDuan     };
74*2dc9ec47SChiaHungDuan     template <typename T> using CacheT = scudo::MapAllocatorCache<T>;
75*2dc9ec47SChiaHungDuan   };
76*2dc9ec47SChiaHungDuan };
77*2dc9ec47SChiaHungDuan 
TEST(ScudoAllocatorConfigTest,VerifyOptionalFlags)78*2dc9ec47SChiaHungDuan TEST(ScudoAllocatorConfigTest, VerifyOptionalFlags) {
79*2dc9ec47SChiaHungDuan   // Test the top level allocator optional config.
80*2dc9ec47SChiaHungDuan   //
81*2dc9ec47SChiaHungDuan   // `MaySupportMemoryTagging` is default off.
82*2dc9ec47SChiaHungDuan   EXPECT_FALSE(scudo::BaseConfig<TestBaseConfig>::getMaySupportMemoryTagging());
83*2dc9ec47SChiaHungDuan   EXPECT_EQ(scudo::BaseConfig<
84*2dc9ec47SChiaHungDuan                 TestBaseConfigEnableOptionalFlag>::getMaySupportMemoryTagging(),
85*2dc9ec47SChiaHungDuan             TestBaseConfigEnableOptionalFlag::getMaySupportMemoryTagging());
86*2dc9ec47SChiaHungDuan 
87*2dc9ec47SChiaHungDuan   // Test primary optional config.
88*2dc9ec47SChiaHungDuan   //
89*2dc9ec47SChiaHungDuan   // `EnableRandomeOffset` is default off.
90*2dc9ec47SChiaHungDuan   EXPECT_FALSE(
91*2dc9ec47SChiaHungDuan       scudo::PrimaryConfig<TestPrimaryConfig>::getEnableRandomOffset());
92*2dc9ec47SChiaHungDuan   EXPECT_EQ(
93*2dc9ec47SChiaHungDuan       scudo::PrimaryConfig<
94*2dc9ec47SChiaHungDuan           TestPrimaryConfigEnableOptionalFlag>::getEnableRandomOffset(),
95*2dc9ec47SChiaHungDuan       TestPrimaryConfigEnableOptionalFlag::Primary::getEnableRandomOffset());
96*2dc9ec47SChiaHungDuan 
97*2dc9ec47SChiaHungDuan   // `ConditionVariableT` is default off.
98*2dc9ec47SChiaHungDuan   EXPECT_FALSE(
99*2dc9ec47SChiaHungDuan       scudo::PrimaryConfig<TestPrimaryConfig>::hasConditionVariableT());
100*2dc9ec47SChiaHungDuan   EXPECT_TRUE(scudo::PrimaryConfig<
101*2dc9ec47SChiaHungDuan               TestPrimaryConfigEnableOptionalType>::hasConditionVariableT());
102*2dc9ec47SChiaHungDuan   EXPECT_TRUE((std::is_same_v<
103*2dc9ec47SChiaHungDuan                typename scudo::PrimaryConfig<
104*2dc9ec47SChiaHungDuan                    TestPrimaryConfigEnableOptionalType>::ConditionVariableT,
105*2dc9ec47SChiaHungDuan                typename TestPrimaryConfigEnableOptionalType::Primary::
106*2dc9ec47SChiaHungDuan                    ConditionVariableT>));
107*2dc9ec47SChiaHungDuan 
108*2dc9ec47SChiaHungDuan   // Test secondary cache optional config.
109*2dc9ec47SChiaHungDuan   using NoCacheConfig =
110*2dc9ec47SChiaHungDuan       scudo::SecondaryConfig<TestSecondaryConfig>::CacheConfig;
111*2dc9ec47SChiaHungDuan   // `EntriesArraySize` is default 0.
112*2dc9ec47SChiaHungDuan   EXPECT_EQ(NoCacheConfig::getEntriesArraySize(), 0U);
113*2dc9ec47SChiaHungDuan 
114*2dc9ec47SChiaHungDuan   using CacheConfig = scudo::SecondaryConfig<
115*2dc9ec47SChiaHungDuan       TestSecondaryCacheConfigEnableOptionalFlag>::CacheConfig;
116*2dc9ec47SChiaHungDuan   EXPECT_EQ(CacheConfig::getEntriesArraySize(),
117*2dc9ec47SChiaHungDuan             TestSecondaryCacheConfigEnableOptionalFlag::Secondary::Cache::
118*2dc9ec47SChiaHungDuan                 getEntriesArraySize());
119*2dc9ec47SChiaHungDuan }
120