• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "flags.h"
15 #include "primary32.h"
16 #include "primary64.h"
17 #include "secondary.h"
18 #include "size_class_map.h"
19 #include "tsd_exclusive.h"
20 #include "tsd_shared.h"
21 
22 namespace scudo {
23 
24 // The combined allocator uses a structure as a template argument that
25 // specifies the configuration options for the various subcomponents of the
26 // allocator.
27 //
28 // struct ExampleConfig {
29 //   // SizeClassMap to use with the Primary.
30 //   using SizeClassMap = DefaultSizeClassMap;
31 //   // Indicates possible support for Memory Tagging.
32 //   static const bool MaySupportMemoryTagging = false;
33 //   // Defines the Primary allocator to use.
34 //   typedef SizeClassAllocator64<ExampleConfig> Primary;
35 //   // Log2 of the size of a size class region, as used by the Primary.
36 //   static const uptr PrimaryRegionSizeLog = 30U;
37 //   // Log2 of the size of block group, as used by the Primary. Each group
38 //   // contains a range of memory addresses, blocks in the range will belong to
39 //   // the same group. In general, single region may have 1 or 2MB group size.
40 //   // Multiple regions will have the group size equal to the region size
41 //   // because the region size is usually smaller than 1 MB.
42 //   // Smaller value gives fine-grained control of memory usage but the trade
43 //   // off is that it may take longer time of deallocation.
44 //   static const uptr PrimaryGroupSizeLog = 20U;
45 //   // Defines the type and scale of a compact pointer. A compact pointer can
46 //   // be understood as the offset of a pointer within the region it belongs
47 //   // to, in increments of a power-of-2 scale.
48 //   // eg: Ptr = Base + (CompactPtr << Scale).
49 //   typedef u32 PrimaryCompactPtrT;
50 //   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
51 //   // Indicates support for offsetting the start of a region by
52 //   // a random number of pages. Only used with primary64.
53 //   static const bool PrimaryEnableRandomOffset = true;
54 //   // Call map for user memory with at least this size. Only used with
55 //   // primary64.
56 //   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
57 //   // Defines the minimal & maximal release interval that can be set.
58 //   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
59 //   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
60 //   // Defines the type of cache used by the Secondary. Some additional
61 //   // configuration entries can be necessary depending on the Cache.
62 //   typedef MapAllocatorNoCache SecondaryCache;
63 //   // Thread-Specific Data Registry used, shared or exclusive.
64 //   template <class A> using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>;
65 // };
66 
67 // Default configurations for various platforms.
68 
69 struct DefaultConfig {
70   using SizeClassMap = DefaultSizeClassMap;
71   static const bool MaySupportMemoryTagging = true;
72 
73 #if SCUDO_CAN_USE_PRIMARY64
74   typedef SizeClassAllocator64<DefaultConfig> Primary;
75   static const uptr PrimaryRegionSizeLog = 32U;
76   static const uptr PrimaryGroupSizeLog = 21U;
77   typedef uptr PrimaryCompactPtrT;
78   static const uptr PrimaryCompactPtrScale = 0;
79   static const bool PrimaryEnableRandomOffset = true;
80   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
81 #else
82   typedef SizeClassAllocator32<DefaultConfig> Primary;
83   static const uptr PrimaryRegionSizeLog = 19U;
84   static const uptr PrimaryGroupSizeLog = 19U;
85   typedef uptr PrimaryCompactPtrT;
86 #endif
87   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
88   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
89 
90   typedef MapAllocatorCache<DefaultConfig> SecondaryCache;
91   static const u32 SecondaryCacheEntriesArraySize = 32U;
92   static const u32 SecondaryCacheQuarantineSize = 0U;
93   static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U;
94   static const uptr SecondaryCacheDefaultMaxEntrySize = 1UL << 19;
95   static const s32 SecondaryCacheMinReleaseToOsIntervalMs = INT32_MIN;
96   static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = INT32_MAX;
97 
98   template <class A> using TSDRegistryT = TSDRegistryExT<A>; // Exclusive
99 };
100 struct AndroidConfig {
101   using SizeClassMap = AndroidSizeClassMap;
102   static const bool MaySupportMemoryTagging = true;
103 
104 #if SCUDO_CAN_USE_PRIMARY64
105   typedef SizeClassAllocator64<AndroidConfig> Primary;
106   static const uptr PrimaryRegionSizeLog = 28U;
107   typedef u32 PrimaryCompactPtrT;
108   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
109   static const uptr PrimaryGroupSizeLog = 20U;
110   static const bool PrimaryEnableRandomOffset = true;
111   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
112 #else
113   typedef SizeClassAllocator32<AndroidConfig> Primary;
114   static const uptr PrimaryRegionSizeLog = 18U;
115   static const uptr PrimaryGroupSizeLog = 18U;
116   typedef uptr PrimaryCompactPtrT;
117 #endif
118   static const s32 PrimaryMinReleaseToOsIntervalMs = 1000;
119   static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000;
120 
121   typedef MapAllocatorCache<AndroidConfig> SecondaryCache;
122   static const u32 SecondaryCacheEntriesArraySize = 256U;
123   static const u32 SecondaryCacheQuarantineSize = 32U;
124   static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U;
125   static const uptr SecondaryCacheDefaultMaxEntrySize = 2UL << 20;
126   static const s32 SecondaryCacheMinReleaseToOsIntervalMs = 0;
127   static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = 1000;
128 
129   template <class A>
130   using TSDRegistryT = TSDRegistrySharedT<A, 8U, 2U>; // Shared, max 8 TSDs.
131 };
132 
133 struct AndroidSvelteConfig {
134   using SizeClassMap = SvelteSizeClassMap;
135   static const bool MaySupportMemoryTagging = false;
136 
137 #if SCUDO_CAN_USE_PRIMARY64
138   typedef SizeClassAllocator64<AndroidSvelteConfig> Primary;
139   static const uptr PrimaryRegionSizeLog = 27U;
140   typedef u32 PrimaryCompactPtrT;
141   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
142   static const uptr PrimaryGroupSizeLog = 18U;
143   static const bool PrimaryEnableRandomOffset = true;
144   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
145 #else
146   typedef SizeClassAllocator32<AndroidSvelteConfig> Primary;
147   static const uptr PrimaryRegionSizeLog = 16U;
148   static const uptr PrimaryGroupSizeLog = 16U;
149   typedef uptr PrimaryCompactPtrT;
150 #endif
151   static const s32 PrimaryMinReleaseToOsIntervalMs = 1000;
152   static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000;
153 
154   typedef MapAllocatorCache<AndroidSvelteConfig> SecondaryCache;
155   static const u32 SecondaryCacheEntriesArraySize = 16U;
156   static const u32 SecondaryCacheQuarantineSize = 32U;
157   static const u32 SecondaryCacheDefaultMaxEntriesCount = 4U;
158   static const uptr SecondaryCacheDefaultMaxEntrySize = 1UL << 18;
159   static const s32 SecondaryCacheMinReleaseToOsIntervalMs = 0;
160   static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = 0;
161 
162   template <class A>
163   using TSDRegistryT = TSDRegistrySharedT<A, 2U, 1U>; // Shared, max 2 TSDs.
164 };
165 
166 #if SCUDO_CAN_USE_PRIMARY64
167 struct FuchsiaConfig {
168   using SizeClassMap = FuchsiaSizeClassMap;
169   static const bool MaySupportMemoryTagging = false;
170 
171   typedef SizeClassAllocator64<FuchsiaConfig> Primary;
172 // Support 39-bit VMA for riscv-64
173 #if SCUDO_RISCV64
174   static const uptr PrimaryRegionSizeLog = 28U;
175   static const uptr PrimaryGroupSizeLog = 19U;
176 #else
177   static const uptr PrimaryRegionSizeLog = 30U;
178   static const uptr PrimaryGroupSizeLog = 21U;
179 #endif
180   typedef u32 PrimaryCompactPtrT;
181   static const bool PrimaryEnableRandomOffset = true;
182   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
183   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
184   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
185   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
186 
187   typedef MapAllocatorNoCache SecondaryCache;
188   template <class A>
189   using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs.
190 };
191 
192 struct TrustyConfig {
193   using SizeClassMap = TrustySizeClassMap;
194   static const bool MaySupportMemoryTagging = false;
195 
196   typedef SizeClassAllocator64<TrustyConfig> Primary;
197   // Some apps have 1 page of heap total so small regions are necessary.
198   static const uptr PrimaryRegionSizeLog = 10U;
199   static const uptr PrimaryGroupSizeLog = 10U;
200   typedef u32 PrimaryCompactPtrT;
201   static const bool PrimaryEnableRandomOffset = false;
202   // Trusty is extremely memory-constrained so minimally round up map calls.
203   static const uptr PrimaryMapSizeIncrement = 1UL << 4;
204   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
205   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
206   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
207 
208   typedef MapAllocatorNoCache SecondaryCache;
209   template <class A>
210   using TSDRegistryT = TSDRegistrySharedT<A, 1U, 1U>; // Shared, max 1 TSD.
211 };
212 #endif
213 
214 #if SCUDO_ANDROID
215 typedef AndroidConfig Config;
216 #elif SCUDO_FUCHSIA
217 typedef FuchsiaConfig Config;
218 #elif SCUDO_TRUSTY
219 typedef TrustyConfig Config;
220 #else
221 typedef DefaultConfig Config;
222 #endif
223 
224 } // namespace scudo
225 
226 #endif // SCUDO_ALLOCATOR_CONFIG_H_
227