xref: /freebsd/contrib/llvm-project/compiler-rt/lib/scudo/standalone/allocator_config.h (revision a90b9d0159070121c221b966469c3e36d912bf82)
1 //===-- allocator_config.h --------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef SCUDO_ALLOCATOR_CONFIG_H_
10 #define SCUDO_ALLOCATOR_CONFIG_H_
11 
12 #include "combined.h"
13 #include "common.h"
14 #include "condition_variable.h"
15 #include "flags.h"
16 #include "primary32.h"
17 #include "primary64.h"
18 #include "secondary.h"
19 #include "size_class_map.h"
20 #include "tsd_exclusive.h"
21 #include "tsd_shared.h"
22 
23 // To import a custom configuration, define `SCUDO_USE_CUSTOM_CONFIG` and
24 // aliasing the `Config` like:
25 //
26 // namespace scudo {
27 //   // The instance of Scudo will be initiated with `Config`.
28 //   typedef CustomConfig Config;
29 //   // Aliasing as default configuration to run the tests with this config.
30 //   typedef CustomConfig DefaultConfig;
31 // } // namespace scudo
32 //
33 // Put them in the header `custom_scudo_config.h` then you will be using the
34 // custom configuration and able to run all the tests as well.
35 #ifdef SCUDO_USE_CUSTOM_CONFIG
36 #include "custom_scudo_config.h"
37 #endif
38 
39 namespace scudo {
40 
41 // The combined allocator uses a structure as a template argument that
42 // specifies the configuration options for the various subcomponents of the
43 // allocator.
44 //
45 // struct ExampleConfig {
46 //   // Indicates possible support for Memory Tagging.
47 //   static const bool MaySupportMemoryTagging = false;
48 //
49 //   // Thread-Specific Data Registry used, shared or exclusive.
50 //   template <class A> using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>;
51 //
52 //   struct Primary {
53 //     // SizeClassMap to use with the Primary.
54 //     using SizeClassMap = DefaultSizeClassMap;
55 //
56 //     // Log2 of the size of a size class region, as used by the Primary.
57 //     static const uptr RegionSizeLog = 30U;
58 //
59 //     // Log2 of the size of block group, as used by the Primary. Each group
60 //     // contains a range of memory addresses, blocks in the range will belong
61 //     // to the same group. In general, single region may have 1 or 2MB group
62 //     // size. Multiple regions will have the group size equal to the region
63 //     // size because the region size is usually smaller than 1 MB.
64 //     // Smaller value gives fine-grained control of memory usage but the
65 //     // trade-off is that it may take longer time of deallocation.
66 //     static const uptr GroupSizeLog = 20U;
67 //
68 //     // Defines the type and scale of a compact pointer. A compact pointer can
69 //     // be understood as the offset of a pointer within the region it belongs
70 //     // to, in increments of a power-of-2 scale.
71 //     // eg: Ptr = Base + (CompactPtr << Scale).
72 //     typedef u32 CompactPtrT;
73 //     static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
74 //
75 //     // Indicates support for offsetting the start of a region by
76 //     // a random number of pages. Only used with primary64.
77 //     static const bool EnableRandomOffset = true;
78 //
79 //     // Call map for user memory with at least this size. Only used with
80 //     // primary64.
81 //     static const uptr MapSizeIncrement = 1UL << 18;
82 //
83 //     // Defines the minimal & maximal release interval that can be set.
84 //     static const s32 MinReleaseToOsIntervalMs = INT32_MIN;
85 //     static const s32 MaxReleaseToOsIntervalMs = INT32_MAX;
86 //
87 //     // Use condition variable to shorten the waiting time of refillment of
88 //     // freelist. Note that this depends on the implementation of condition
89 //     // variable on each platform and the performance may vary so that it
90 //     // doesn't guarantee a performance benefit.
91 //     // Note that both variables have to be defined to enable it.
92 //     static const bool UseConditionVariable = true;
93 //     using ConditionVariableT = ConditionVariableLinux;
94 //   };
95 //   // Defines the type of Primary allocator to use.
96 //   template <typename Config> using PrimaryT = SizeClassAllocator64<Config>;
97 //
98 //   // Defines the type of cache used by the Secondary. Some additional
99 //   // configuration entries can be necessary depending on the Cache.
100 //   struct Secondary {
101 //     struct Cache {
102 //       static const u32 EntriesArraySize = 32U;
103 //       static const u32 QuarantineSize = 0U;
104 //       static const u32 DefaultMaxEntriesCount = 32U;
105 //       static const uptr DefaultMaxEntrySize = 1UL << 19;
106 //       static const s32 MinReleaseToOsIntervalMs = INT32_MIN;
107 //       static const s32 MaxReleaseToOsIntervalMs = INT32_MAX;
108 //     };
109 //     // Defines the type of Secondary Cache to use.
110 //     template <typename Config> using CacheT = MapAllocatorCache<Config>;
111 //   };
112 //   // Defines the type of Secondary allocator to use.
113 //   template <typename Config> using SecondaryT = MapAllocator<Config>;
114 // };
115 
116 #ifndef SCUDO_USE_CUSTOM_CONFIG
117 
118 // Default configurations for various platforms. Note this is only enabled when
119 // there's no custom configuration in the build system.
120 struct DefaultConfig {
121   static const bool MaySupportMemoryTagging = true;
122   template <class A> using TSDRegistryT = TSDRegistryExT<A>; // Exclusive
123 
124   struct Primary {
125     using SizeClassMap = DefaultSizeClassMap;
126 #if SCUDO_CAN_USE_PRIMARY64
127     static const uptr RegionSizeLog = 32U;
128     static const uptr GroupSizeLog = 21U;
129     typedef uptr CompactPtrT;
130     static const uptr CompactPtrScale = 0;
131     static const bool EnableRandomOffset = true;
132     static const uptr MapSizeIncrement = 1UL << 18;
133 #else
134     static const uptr RegionSizeLog = 19U;
135     static const uptr GroupSizeLog = 19U;
136     typedef uptr CompactPtrT;
137 #endif
138     static const s32 MinReleaseToOsIntervalMs = INT32_MIN;
139     static const s32 MaxReleaseToOsIntervalMs = INT32_MAX;
140   };
141 #if SCUDO_CAN_USE_PRIMARY64
142   template <typename Config> using PrimaryT = SizeClassAllocator64<Config>;
143 #else
144   template <typename Config> using PrimaryT = SizeClassAllocator32<Config>;
145 #endif
146 
147   struct Secondary {
148     struct Cache {
149       static const u32 EntriesArraySize = 32U;
150       static const u32 QuarantineSize = 0U;
151       static const u32 DefaultMaxEntriesCount = 32U;
152       static const uptr DefaultMaxEntrySize = 1UL << 19;
153       static const s32 MinReleaseToOsIntervalMs = INT32_MIN;
154       static const s32 MaxReleaseToOsIntervalMs = INT32_MAX;
155     };
156     template <typename Config> using CacheT = MapAllocatorCache<Config>;
157   };
158 
159   template <typename Config> using SecondaryT = MapAllocator<Config>;
160 };
161 
162 #endif // SCUDO_USE_CUSTOM_CONFIG
163 
164 struct AndroidConfig {
165   static const bool MaySupportMemoryTagging = true;
166   template <class A>
167   using TSDRegistryT = TSDRegistrySharedT<A, 8U, 2U>; // Shared, max 8 TSDs.
168 
169   struct Primary {
170     using SizeClassMap = AndroidSizeClassMap;
171 #if SCUDO_CAN_USE_PRIMARY64
172     static const uptr RegionSizeLog = 28U;
173     typedef u32 CompactPtrT;
174     static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
175     static const uptr GroupSizeLog = 20U;
176     static const bool EnableRandomOffset = true;
177     static const uptr MapSizeIncrement = 1UL << 18;
178 #else
179     static const uptr RegionSizeLog = 18U;
180     static const uptr GroupSizeLog = 18U;
181     typedef uptr CompactPtrT;
182 #endif
183     static const s32 MinReleaseToOsIntervalMs = 1000;
184     static const s32 MaxReleaseToOsIntervalMs = 1000;
185   };
186 #if SCUDO_CAN_USE_PRIMARY64
187   template <typename Config> using PrimaryT = SizeClassAllocator64<Config>;
188 #else
189   template <typename Config> using PrimaryT = SizeClassAllocator32<Config>;
190 #endif
191 
192   struct Secondary {
193     struct Cache {
194       static const u32 EntriesArraySize = 256U;
195       static const u32 QuarantineSize = 32U;
196       static const u32 DefaultMaxEntriesCount = 32U;
197       static const uptr DefaultMaxEntrySize = 2UL << 20;
198       static const s32 MinReleaseToOsIntervalMs = 0;
199       static const s32 MaxReleaseToOsIntervalMs = 1000;
200     };
201     template <typename Config> using CacheT = MapAllocatorCache<Config>;
202   };
203 
204   template <typename Config> using SecondaryT = MapAllocator<Config>;
205 };
206 
207 #if SCUDO_CAN_USE_PRIMARY64
208 struct FuchsiaConfig {
209   static const bool MaySupportMemoryTagging = false;
210   template <class A>
211   using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs.
212 
213   struct Primary {
214     using SizeClassMap = FuchsiaSizeClassMap;
215 #if SCUDO_RISCV64
216     // Support 39-bit VMA for riscv-64
217     static const uptr RegionSizeLog = 28U;
218     static const uptr GroupSizeLog = 19U;
219 #else
220     static const uptr RegionSizeLog = 30U;
221     static const uptr GroupSizeLog = 21U;
222 #endif
223     typedef u32 CompactPtrT;
224     static const bool EnableRandomOffset = true;
225     static const uptr MapSizeIncrement = 1UL << 18;
226     static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
227     static const s32 MinReleaseToOsIntervalMs = INT32_MIN;
228     static const s32 MaxReleaseToOsIntervalMs = INT32_MAX;
229   };
230   template <typename Config> using PrimaryT = SizeClassAllocator64<Config>;
231 
232   struct Secondary {
233     template <typename Config> using CacheT = MapAllocatorNoCache<Config>;
234   };
235   template <typename Config> using SecondaryT = MapAllocator<Config>;
236 };
237 
238 struct TrustyConfig {
239   static const bool MaySupportMemoryTagging = true;
240   template <class A>
241   using TSDRegistryT = TSDRegistrySharedT<A, 1U, 1U>; // Shared, max 1 TSD.
242 
243   struct Primary {
244     using SizeClassMap = TrustySizeClassMap;
245     static const uptr RegionSizeLog = 28U;
246     static const uptr GroupSizeLog = 20U;
247     typedef u32 CompactPtrT;
248     static const bool EnableRandomOffset = false;
249     static const uptr MapSizeIncrement = 1UL << 12;
250     static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
251     static const s32 MinReleaseToOsIntervalMs = INT32_MIN;
252     static const s32 MaxReleaseToOsIntervalMs = INT32_MAX;
253   };
254   template <typename Config> using PrimaryT = SizeClassAllocator64<Config>;
255 
256   struct Secondary {
257     template <typename Config> using CacheT = MapAllocatorNoCache<Config>;
258   };
259 
260   template <typename Config> using SecondaryT = MapAllocator<Config>;
261 };
262 #endif
263 
264 #ifndef SCUDO_USE_CUSTOM_CONFIG
265 
266 #if SCUDO_ANDROID
267 typedef AndroidConfig Config;
268 #elif SCUDO_FUCHSIA
269 typedef FuchsiaConfig Config;
270 #elif SCUDO_TRUSTY
271 typedef TrustyConfig Config;
272 #else
273 typedef DefaultConfig Config;
274 #endif
275 
276 #endif // SCUDO_USE_CUSTOM_CONFIG
277 
278 } // namespace scudo
279 
280 #endif // SCUDO_ALLOCATOR_CONFIG_H_
281