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
22namespace 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//   // SizeClasMmap 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
69struct 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};
100struct 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
133struct 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
167struct FuchsiaConfig {
168  using SizeClassMap = FuchsiaSizeClassMap;
169  static const bool MaySupportMemoryTagging = false;
170
171  typedef SizeClassAllocator64<FuchsiaConfig> Primary;
172  static const uptr PrimaryRegionSizeLog = 30U;
173  static const uptr PrimaryGroupSizeLog = 21U;
174  typedef u32 PrimaryCompactPtrT;
175  static const bool PrimaryEnableRandomOffset = true;
176  static const uptr PrimaryMapSizeIncrement = 1UL << 18;
177  static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
178  static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
179  static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
180
181  typedef MapAllocatorNoCache SecondaryCache;
182  template <class A>
183  using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs.
184};
185
186struct TrustyConfig {
187  using SizeClassMap = TrustySizeClassMap;
188  static const bool MaySupportMemoryTagging = false;
189
190  typedef SizeClassAllocator64<TrustyConfig> Primary;
191  // Some apps have 1 page of heap total so small regions are necessary.
192  static const uptr PrimaryRegionSizeLog = 10U;
193  static const uptr PrimaryGroupSizeLog = 10U;
194  typedef u32 PrimaryCompactPtrT;
195  static const bool PrimaryEnableRandomOffset = false;
196  // Trusty is extremely memory-constrained so minimally round up map calls.
197  static const uptr PrimaryMapSizeIncrement = 1UL << 4;
198  static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
199  static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
200  static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
201
202  typedef MapAllocatorNoCache SecondaryCache;
203  template <class A>
204  using TSDRegistryT = TSDRegistrySharedT<A, 1U, 1U>; // Shared, max 1 TSD.
205};
206#endif
207
208#if SCUDO_ANDROID
209typedef AndroidConfig Config;
210#elif SCUDO_FUCHSIA
211typedef FuchsiaConfig Config;
212#elif SCUDO_TRUSTY
213typedef TrustyConfig Config;
214#else
215typedef DefaultConfig Config;
216#endif
217
218} // namespace scudo
219
220#endif // SCUDO_ALLOCATOR_CONFIG_H_
221