13cab2bb3Spatrick //===-- allocator_config.h --------------------------------------*- C++ -*-===// 23cab2bb3Spatrick // 33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information. 53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63cab2bb3Spatrick // 73cab2bb3Spatrick //===----------------------------------------------------------------------===// 83cab2bb3Spatrick 93cab2bb3Spatrick #ifndef SCUDO_ALLOCATOR_CONFIG_H_ 103cab2bb3Spatrick #define SCUDO_ALLOCATOR_CONFIG_H_ 113cab2bb3Spatrick 123cab2bb3Spatrick #include "combined.h" 133cab2bb3Spatrick #include "common.h" 143cab2bb3Spatrick #include "flags.h" 153cab2bb3Spatrick #include "primary32.h" 163cab2bb3Spatrick #include "primary64.h" 173cab2bb3Spatrick #include "secondary.h" 183cab2bb3Spatrick #include "size_class_map.h" 193cab2bb3Spatrick #include "tsd_exclusive.h" 203cab2bb3Spatrick #include "tsd_shared.h" 213cab2bb3Spatrick 223cab2bb3Spatrick namespace scudo { 233cab2bb3Spatrick 24d89ec533Spatrick // The combined allocator uses a structure as a template argument that 25d89ec533Spatrick // specifies the configuration options for the various subcomponents of the 26d89ec533Spatrick // allocator. 27d89ec533Spatrick // 28d89ec533Spatrick // struct ExampleConfig { 29d89ec533Spatrick // // SizeClasMmap to use with the Primary. 30d89ec533Spatrick // using SizeClassMap = DefaultSizeClassMap; 31d89ec533Spatrick // // Indicates possible support for Memory Tagging. 32d89ec533Spatrick // static const bool MaySupportMemoryTagging = false; 33d89ec533Spatrick // // Defines the Primary allocator to use. 34d89ec533Spatrick // typedef SizeClassAllocator64<ExampleConfig> Primary; 35d89ec533Spatrick // // Log2 of the size of a size class region, as used by the Primary. 36d89ec533Spatrick // static const uptr PrimaryRegionSizeLog = 30U; 37*810390e3Srobert // // Log2 of the size of block group, as used by the Primary. Each group 38*810390e3Srobert // // contains a range of memory addresses, blocks in the range will belong to 39*810390e3Srobert // // the same group. In general, single region may have 1 or 2MB group size. 40*810390e3Srobert // // Multiple regions will have the group size equal to the region size 41*810390e3Srobert // // because the region size is usually smaller than 1 MB. 42*810390e3Srobert // // Smaller value gives fine-grained control of memory usage but the trade 43*810390e3Srobert // // off is that it may take longer time of deallocation. 44*810390e3Srobert // static const uptr PrimaryGroupSizeLog = 20U; 45d89ec533Spatrick // // Defines the type and scale of a compact pointer. A compact pointer can 46d89ec533Spatrick // // be understood as the offset of a pointer within the region it belongs 47d89ec533Spatrick // // to, in increments of a power-of-2 scale. 48d89ec533Spatrick // // eg: Ptr = Base + (CompactPtr << Scale). 49d89ec533Spatrick // typedef u32 PrimaryCompactPtrT; 50d89ec533Spatrick // static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 51d89ec533Spatrick // // Indicates support for offsetting the start of a region by 52d89ec533Spatrick // // a random number of pages. Only used with primary64. 53d89ec533Spatrick // static const bool PrimaryEnableRandomOffset = true; 54d89ec533Spatrick // // Call map for user memory with at least this size. Only used with 55d89ec533Spatrick // // primary64. 56d89ec533Spatrick // static const uptr PrimaryMapSizeIncrement = 1UL << 18; 57d89ec533Spatrick // // Defines the minimal & maximal release interval that can be set. 58d89ec533Spatrick // static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN; 59d89ec533Spatrick // static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX; 60d89ec533Spatrick // // Defines the type of cache used by the Secondary. Some additional 61d89ec533Spatrick // // configuration entries can be necessary depending on the Cache. 62d89ec533Spatrick // typedef MapAllocatorNoCache SecondaryCache; 63d89ec533Spatrick // // Thread-Specific Data Registry used, shared or exclusive. 64d89ec533Spatrick // template <class A> using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; 65d89ec533Spatrick // }; 66d89ec533Spatrick 673cab2bb3Spatrick // Default configurations for various platforms. 683cab2bb3Spatrick 693cab2bb3Spatrick struct DefaultConfig { 703cab2bb3Spatrick using SizeClassMap = DefaultSizeClassMap; 71d89ec533Spatrick static const bool MaySupportMemoryTagging = true; 72d89ec533Spatrick 733cab2bb3Spatrick #if SCUDO_CAN_USE_PRIMARY64 74d89ec533Spatrick typedef SizeClassAllocator64<DefaultConfig> Primary; 75d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 32U; 76*810390e3Srobert static const uptr PrimaryGroupSizeLog = 21U; 77d89ec533Spatrick typedef uptr PrimaryCompactPtrT; 78d89ec533Spatrick static const uptr PrimaryCompactPtrScale = 0; 79d89ec533Spatrick static const bool PrimaryEnableRandomOffset = true; 80d89ec533Spatrick static const uptr PrimaryMapSizeIncrement = 1UL << 18; 813cab2bb3Spatrick #else 82d89ec533Spatrick typedef SizeClassAllocator32<DefaultConfig> Primary; 83d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 19U; 84*810390e3Srobert static const uptr PrimaryGroupSizeLog = 19U; 85d89ec533Spatrick typedef uptr PrimaryCompactPtrT; 863cab2bb3Spatrick #endif 87d89ec533Spatrick static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN; 88d89ec533Spatrick static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX; 89d89ec533Spatrick 90d89ec533Spatrick typedef MapAllocatorCache<DefaultConfig> SecondaryCache; 91d89ec533Spatrick static const u32 SecondaryCacheEntriesArraySize = 32U; 92d89ec533Spatrick static const u32 SecondaryCacheQuarantineSize = 0U; 93d89ec533Spatrick static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U; 94d89ec533Spatrick static const uptr SecondaryCacheDefaultMaxEntrySize = 1UL << 19; 95d89ec533Spatrick static const s32 SecondaryCacheMinReleaseToOsIntervalMs = INT32_MIN; 96d89ec533Spatrick static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = INT32_MAX; 97d89ec533Spatrick 983cab2bb3Spatrick template <class A> using TSDRegistryT = TSDRegistryExT<A>; // Exclusive 993cab2bb3Spatrick }; 1003cab2bb3Spatrick struct AndroidConfig { 1013cab2bb3Spatrick using SizeClassMap = AndroidSizeClassMap; 102d89ec533Spatrick static const bool MaySupportMemoryTagging = true; 103d89ec533Spatrick 1043cab2bb3Spatrick #if SCUDO_CAN_USE_PRIMARY64 105d89ec533Spatrick typedef SizeClassAllocator64<AndroidConfig> Primary; 106d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 28U; 107d89ec533Spatrick typedef u32 PrimaryCompactPtrT; 108d89ec533Spatrick static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 109*810390e3Srobert static const uptr PrimaryGroupSizeLog = 20U; 110d89ec533Spatrick static const bool PrimaryEnableRandomOffset = true; 111d89ec533Spatrick static const uptr PrimaryMapSizeIncrement = 1UL << 18; 1123cab2bb3Spatrick #else 113d89ec533Spatrick typedef SizeClassAllocator32<AndroidConfig> Primary; 114d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 18U; 115*810390e3Srobert static const uptr PrimaryGroupSizeLog = 18U; 116d89ec533Spatrick typedef uptr PrimaryCompactPtrT; 1173cab2bb3Spatrick #endif 118d89ec533Spatrick static const s32 PrimaryMinReleaseToOsIntervalMs = 1000; 119d89ec533Spatrick static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000; 120d89ec533Spatrick 121d89ec533Spatrick typedef MapAllocatorCache<AndroidConfig> SecondaryCache; 122d89ec533Spatrick static const u32 SecondaryCacheEntriesArraySize = 256U; 123d89ec533Spatrick static const u32 SecondaryCacheQuarantineSize = 32U; 124d89ec533Spatrick static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U; 125d89ec533Spatrick static const uptr SecondaryCacheDefaultMaxEntrySize = 2UL << 20; 126d89ec533Spatrick static const s32 SecondaryCacheMinReleaseToOsIntervalMs = 0; 127d89ec533Spatrick static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = 1000; 128d89ec533Spatrick 1293cab2bb3Spatrick template <class A> 130d89ec533Spatrick using TSDRegistryT = TSDRegistrySharedT<A, 8U, 2U>; // Shared, max 8 TSDs. 1313cab2bb3Spatrick }; 1323cab2bb3Spatrick 1333cab2bb3Spatrick struct AndroidSvelteConfig { 1343cab2bb3Spatrick using SizeClassMap = SvelteSizeClassMap; 135d89ec533Spatrick static const bool MaySupportMemoryTagging = false; 136d89ec533Spatrick 1373cab2bb3Spatrick #if SCUDO_CAN_USE_PRIMARY64 138d89ec533Spatrick typedef SizeClassAllocator64<AndroidSvelteConfig> Primary; 139d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 27U; 140d89ec533Spatrick typedef u32 PrimaryCompactPtrT; 141d89ec533Spatrick static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 142*810390e3Srobert static const uptr PrimaryGroupSizeLog = 18U; 143d89ec533Spatrick static const bool PrimaryEnableRandomOffset = true; 144d89ec533Spatrick static const uptr PrimaryMapSizeIncrement = 1UL << 18; 1453cab2bb3Spatrick #else 146d89ec533Spatrick typedef SizeClassAllocator32<AndroidSvelteConfig> Primary; 147d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 16U; 148*810390e3Srobert static const uptr PrimaryGroupSizeLog = 16U; 149d89ec533Spatrick typedef uptr PrimaryCompactPtrT; 1503cab2bb3Spatrick #endif 151d89ec533Spatrick static const s32 PrimaryMinReleaseToOsIntervalMs = 1000; 152d89ec533Spatrick static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000; 153d89ec533Spatrick 154d89ec533Spatrick typedef MapAllocatorCache<AndroidSvelteConfig> SecondaryCache; 155d89ec533Spatrick static const u32 SecondaryCacheEntriesArraySize = 16U; 156d89ec533Spatrick static const u32 SecondaryCacheQuarantineSize = 32U; 157d89ec533Spatrick static const u32 SecondaryCacheDefaultMaxEntriesCount = 4U; 158d89ec533Spatrick static const uptr SecondaryCacheDefaultMaxEntrySize = 1UL << 18; 159d89ec533Spatrick static const s32 SecondaryCacheMinReleaseToOsIntervalMs = 0; 160d89ec533Spatrick static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = 0; 161d89ec533Spatrick 1623cab2bb3Spatrick template <class A> 163d89ec533Spatrick using TSDRegistryT = TSDRegistrySharedT<A, 2U, 1U>; // Shared, max 2 TSDs. 1643cab2bb3Spatrick }; 1653cab2bb3Spatrick 1663cab2bb3Spatrick #if SCUDO_CAN_USE_PRIMARY64 1673cab2bb3Spatrick struct FuchsiaConfig { 168d89ec533Spatrick using SizeClassMap = FuchsiaSizeClassMap; 169d89ec533Spatrick static const bool MaySupportMemoryTagging = false; 170d89ec533Spatrick 171d89ec533Spatrick typedef SizeClassAllocator64<FuchsiaConfig> Primary; 172d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 30U; 173*810390e3Srobert static const uptr PrimaryGroupSizeLog = 21U; 174d89ec533Spatrick typedef u32 PrimaryCompactPtrT; 175d89ec533Spatrick static const bool PrimaryEnableRandomOffset = true; 176d89ec533Spatrick static const uptr PrimaryMapSizeIncrement = 1UL << 18; 177d89ec533Spatrick static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 178d89ec533Spatrick static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN; 179d89ec533Spatrick static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX; 180d89ec533Spatrick 181d89ec533Spatrick typedef MapAllocatorNoCache SecondaryCache; 1823cab2bb3Spatrick template <class A> 183d89ec533Spatrick using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs. 184d89ec533Spatrick }; 185d89ec533Spatrick 186d89ec533Spatrick struct TrustyConfig { 187d89ec533Spatrick using SizeClassMap = TrustySizeClassMap; 188d89ec533Spatrick static const bool MaySupportMemoryTagging = false; 189d89ec533Spatrick 190d89ec533Spatrick typedef SizeClassAllocator64<TrustyConfig> Primary; 191d89ec533Spatrick // Some apps have 1 page of heap total so small regions are necessary. 192d89ec533Spatrick static const uptr PrimaryRegionSizeLog = 10U; 193*810390e3Srobert static const uptr PrimaryGroupSizeLog = 10U; 194d89ec533Spatrick typedef u32 PrimaryCompactPtrT; 195d89ec533Spatrick static const bool PrimaryEnableRandomOffset = false; 196d89ec533Spatrick // Trusty is extremely memory-constrained so minimally round up map calls. 197d89ec533Spatrick static const uptr PrimaryMapSizeIncrement = 1UL << 4; 198d89ec533Spatrick static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 199d89ec533Spatrick static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN; 200d89ec533Spatrick static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX; 201d89ec533Spatrick 202d89ec533Spatrick typedef MapAllocatorNoCache SecondaryCache; 203d89ec533Spatrick template <class A> 204d89ec533Spatrick using TSDRegistryT = TSDRegistrySharedT<A, 1U, 1U>; // Shared, max 1 TSD. 2053cab2bb3Spatrick }; 2063cab2bb3Spatrick #endif 2073cab2bb3Spatrick 2083cab2bb3Spatrick #if SCUDO_ANDROID 2093cab2bb3Spatrick typedef AndroidConfig Config; 2103cab2bb3Spatrick #elif SCUDO_FUCHSIA 2113cab2bb3Spatrick typedef FuchsiaConfig Config; 212d89ec533Spatrick #elif SCUDO_TRUSTY 213d89ec533Spatrick typedef TrustyConfig Config; 2143cab2bb3Spatrick #else 2153cab2bb3Spatrick typedef DefaultConfig Config; 2163cab2bb3Spatrick #endif 2173cab2bb3Spatrick 2183cab2bb3Spatrick } // namespace scudo 2193cab2bb3Spatrick 2203cab2bb3Spatrick #endif // SCUDO_ALLOCATOR_CONFIG_H_ 221