Globals.h (6639B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef GLOBALS_H 8 #define GLOBALS_H 9 10 // This file contains compile-time constants that depend on sizes of structures 11 // or the page size. Page size isn't always known at compile time so some 12 // values defined here may be determined at runtime. 13 14 #include "mozilla/Literals.h" 15 #include "mozilla/MathAlgorithms.h" 16 17 #include "Constants.h" 18 // Chunk.h is required for sizeof(arena_chunk_t), but it's inconvenient that 19 // Chunk.h can't access any constants. 20 #include "Chunk.h" 21 #include "Mutex.h" 22 #include "Utils.h" 23 24 // Define MALLOC_RUNTIME_CONFIG depending on MOZ_DEBUG. Overriding this as 25 // a build option allows us to build mozjemalloc/firefox without runtime asserts 26 // but with runtime configuration. Making some testing easier. 27 28 #ifdef MOZ_DEBUG 29 # define MALLOC_RUNTIME_CONFIG 30 #endif 31 32 // Uncomment this to enable extra-vigilant assertions. These assertions may run 33 // more expensive checks that are sometimes too slow for regular debug mode. 34 // #define MALLOC_DEBUG_VIGILANT 35 36 // When MALLOC_STATIC_PAGESIZE is defined, the page size is fixed at 37 // compile-time for better performance, as opposed to determined at 38 // runtime. Some platforms can have different page sizes at runtime 39 // depending on kernel configuration, so they are opted out by default. 40 // Debug builds are opted out too, for test coverage. 41 #ifndef MALLOC_RUNTIME_CONFIG 42 # if !defined(XP_MACOSX) && !defined(ANDROID) && !defined(__ia64__) && \ 43 !defined(__sparc__) && !defined(__mips__) && !defined(__aarch64__) && \ 44 !defined(__powerpc__) && !defined(__loongarch__) 45 # define MALLOC_STATIC_PAGESIZE 1 46 # endif 47 #endif 48 49 namespace mozilla { 50 51 // mozjemalloc has two values for page size. 52 // 53 // gPageSize: A logical page size used for mozjemalloc's own structures. 54 // gRealPageSize The actual page size used by the OS & Hardware. 55 // 56 // They can be different so that we can continue to use 4KB pages on systems 57 // with a larger page size. (WIP see Bug 1980047). 58 // 59 // On x86-64 they are both 4KiB. However Apple Silicon has a 16KiB page size, 60 // so gRealPageSize will be 16KiB, but in order to keep the number of 61 // regions-per-run to 256 we want to limit gPageSize to 4KiB. (4096 / 16 = 62 // 256). Other platforms with different gRealPageSizes might also have 63 // different gRealPageSize and gPageSize. 64 // 65 // gPageSize is always less than or equal to gRealPageSize. 66 // 67 #ifdef MALLOC_STATIC_PAGESIZE 68 // Platform specific page size conditions copied from js/public/HeapAPI.h 69 # if defined(__powerpc64__) 70 static const size_t gRealPageSize = 64_KiB; 71 # elif defined(__loongarch64) 72 static const size_t gRealPageSize = 16_KiB; 73 # else 74 static const size_t gRealPageSize = 4_KiB; 75 # endif 76 static const size_t gPageSize = gRealPageSize; 77 #else 78 // When MALLOC_OPTIONS contains one or several `P`s, gPageSize will be 79 // doubled for each `P`. Likewise each 'p' will halve gPageSize. 80 extern size_t gRealPageSize; 81 extern size_t gPageSize; 82 #endif 83 84 // Return the smallest pagesize multiple that is >= s. 85 #define PAGE_CEILING(s) (((s) + gPageSizeMask) & ~gPageSizeMask) 86 #define REAL_PAGE_CEILING(s) (((s) + gRealPageSizeMask) & ~gRealPageSizeMask) 87 88 #define PAGES_PER_REAL_PAGE_CEILING(s) \ 89 (((s) + gPagesPerRealPage - 1) & ~(gPagesPerRealPage - 1)) 90 91 #ifdef MALLOC_STATIC_PAGESIZE 92 # define GLOBAL(type, name, value) static const type name = value; 93 # define GLOBAL_LOG2 LOG2 94 # define GLOBAL_ASSERT_HELPER1(x) static_assert(x, #x) 95 # define GLOBAL_ASSERT_HELPER2(x, y) static_assert(x, y) 96 # define GLOBAL_ASSERT(...) \ 97 \ 98 MOZ_PASTE_PREFIX_AND_ARG_COUNT(GLOBAL_ASSERT_HELPER, __VA_ARGS__) \ 99 (__VA_ARGS__) 100 # define GLOBAL_CONSTEXPR constexpr 101 # include "Globals_inc.h" 102 # undef GLOBAL_CONSTEXPR 103 # undef GLOBAL_ASSERT 104 # undef GLOBAL_ASSERT_HELPER1 105 # undef GLOBAL_ASSERT_HELPER2 106 # undef GLOBAL_LOG2 107 # undef GLOBAL 108 #else 109 // We declare the globals here and initialise them in DefineGlobals() 110 # define GLOBAL(type, name, value) extern type name; 111 # define GLOBAL_ASSERT(...) 112 # include "Globals_inc.h" 113 # undef GLOBAL_ASSERT 114 # undef GLOBAL 115 116 void DefineGlobals(); 117 #endif 118 119 // Max size class for bins. 120 #define gMaxBinClass \ 121 (gMaxSubPageClass ? gMaxSubPageClass : kMaxQuantumWideClass) 122 123 // Return the smallest chunk multiple that is >= s. 124 #define CHUNK_CEILING(s) (((s) + kChunkSizeMask) & ~kChunkSizeMask) 125 126 // Return the smallest cacheline multiple that is >= s. 127 #define CACHELINE_CEILING(s) \ 128 (((s) + (kCacheLineSize - 1)) & ~(kCacheLineSize - 1)) 129 130 // Return the smallest quantum multiple that is >= a. 131 #define QUANTUM_CEILING(a) (((a) + (kQuantumMask)) & ~(kQuantumMask)) 132 #define QUANTUM_WIDE_CEILING(a) \ 133 (((a) + (kQuantumWideMask)) & ~(kQuantumWideMask)) 134 135 // Return the smallest sub page-size that is >= a. 136 #define SUBPAGE_CEILING(a) (RoundUpPow2(a)) 137 138 // Number of all the small-allocated classes 139 #define NUM_SMALL_CLASSES \ 140 (kNumQuantumClasses + kNumQuantumWideClasses + gNumSubPageClasses) 141 142 // Return the chunk address for allocation address a. 143 static inline arena_chunk_t* GetChunkForPtr(const void* aPtr) { 144 return (arena_chunk_t*)(uintptr_t(aPtr) & ~kChunkSizeMask); 145 } 146 147 // Return the chunk offset of address a. 148 static inline size_t GetChunkOffsetForPtr(const void* aPtr) { 149 return (size_t)(uintptr_t(aPtr) & kChunkSizeMask); 150 } 151 152 // Maximum number of dirty pages per arena. 153 #define DIRTY_MAX_DEFAULT (1U << 8) 154 155 enum PoisonType { 156 NONE, 157 SOME, 158 ALL, 159 }; 160 161 extern size_t opt_dirty_max; 162 163 #define OPT_JUNK_DEFAULT false 164 #define OPT_ZERO_DEFAULT false 165 #ifdef EARLY_BETA_OR_EARLIER 166 # define OPT_POISON_DEFAULT ALL 167 #else 168 # define OPT_POISON_DEFAULT SOME 169 #endif 170 // Keep this larger than and ideally a multiple of kCacheLineSize; 171 #define OPT_POISON_SIZE_DEFAULT 256 172 173 #ifdef MALLOC_RUNTIME_CONFIG 174 175 extern bool opt_junk; 176 extern bool opt_zero; 177 extern PoisonType opt_poison; 178 extern size_t opt_poison_size; 179 180 #else 181 182 constexpr bool opt_junk = OPT_JUNK_DEFAULT; 183 constexpr bool opt_zero = OPT_ZERO_DEFAULT; 184 constexpr PoisonType opt_poison = OPT_POISON_DEFAULT; 185 constexpr size_t opt_poison_size = OPT_POISON_SIZE_DEFAULT; 186 187 static_assert(opt_poison_size >= kCacheLineSize); 188 static_assert((opt_poison_size % kCacheLineSize) == 0); 189 190 #endif 191 192 extern bool opt_randomize_small; 193 194 } // namespace mozilla 195 196 #endif // ! GLOBALS_H