Constants.h (5312B)
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 CONSTANTS_H 8 #define CONSTANTS_H 9 10 #include "mozilla/Literals.h" 11 #include "mozilla/MathAlgorithms.h" 12 13 #include "Utils.h" 14 15 // This file contains compile-time connstants that don't depend on sizes of 16 // structures or the page size. It can be included before defining 17 // structures and classes. Other runtime or structure-dependant options are 18 // in options.h 19 20 // On Linux, we use madvise(MADV_DONTNEED) to release memory back to the 21 // operating system. If we release 1MB of live pages with MADV_DONTNEED, our 22 // RSS will decrease by 1MB (almost) immediately. 23 // 24 // On Mac, we use madvise(MADV_FREE). Unlike MADV_DONTNEED on Linux, MADV_FREE 25 // on Mac doesn't cause the OS to release the specified pages immediately; the 26 // OS keeps them in our process until the machine comes under memory pressure. 27 // 28 // It's therefore difficult to measure the process's RSS on Mac, since, in the 29 // absence of memory pressure, the contribution from the heap to RSS will not 30 // decrease due to our madvise calls. 31 // 32 // We therefore define MALLOC_DOUBLE_PURGE on Mac. This causes jemalloc to 33 // track which pages have been MADV_FREE'd. You can then call 34 // jemalloc_purge_freed_pages(), which will force the OS to release those 35 // MADV_FREE'd pages, making the process's RSS reflect its true memory usage. 36 37 #ifdef XP_DARWIN 38 # define MALLOC_DOUBLE_PURGE 39 #endif 40 41 #ifdef XP_WIN 42 # define MALLOC_DECOMMIT 43 #endif 44 45 #ifndef XP_WIN 46 // Newer Linux systems support MADV_FREE, but we're not supporting 47 // that properly. bug #1406304. 48 # if defined(XP_LINUX) && defined(MADV_FREE) 49 # undef MADV_FREE 50 # endif 51 # ifndef MADV_FREE 52 # define MADV_FREE MADV_DONTNEED 53 # endif 54 #endif 55 56 // Our size classes are inclusive ranges of memory sizes. By describing the 57 // minimums and how memory is allocated in each range the maximums can be 58 // calculated. 59 60 // On Windows the smallest allocation size must be 8 bytes on 32-bit, 16 bytes 61 // on 64-bit. On Linux and Mac, even malloc(1) must reserve a word's worth of 62 // memory (see Mozilla bug 691003). Mozjemalloc's minimum allocation size is 63 // 16 bytes, regardless of architecture/OS, which limits the number of 64 // allocations per page to 256 to support free lists (Bug 1980047). It turns 65 // out that this has no impact on memory footprint since the size lost due to 66 // internal fragmentation is offset by better external fragmentation. 67 68 // Smallest quantum-spaced size classes. It could actually also be labelled a 69 // tiny allocation, and is spaced as such from the largest tiny size class. 70 // Tiny classes being powers of 2, this is twice as large as the largest of 71 // them. 72 static constexpr size_t kMinQuantumClass = 16; 73 static constexpr size_t kMinQuantumWideClass = 512; 74 static constexpr size_t kMinSubPageClass = 4_KiB; 75 76 // Amount (quantum) separating quantum-spaced size classes. 77 static constexpr size_t kQuantum = 16; 78 static constexpr size_t kQuantumMask = kQuantum - 1; 79 static constexpr size_t kQuantumWide = 256; 80 static constexpr size_t kQuantumWideMask = kQuantumWide - 1; 81 82 static constexpr size_t kMaxQuantumClass = kMinQuantumWideClass - kQuantum; 83 static constexpr size_t kMaxQuantumWideClass = kMinSubPageClass - kQuantumWide; 84 85 // We can optimise some divisions to shifts if these are powers of two. 86 static_assert(mozilla::IsPowerOfTwo(kQuantum), 87 "kQuantum is not a power of two"); 88 static_assert(mozilla::IsPowerOfTwo(kQuantumWide), 89 "kQuantumWide is not a power of two"); 90 91 static_assert(kMaxQuantumClass % kQuantum == 0, 92 "kMaxQuantumClass is not a multiple of kQuantum"); 93 static_assert(kMaxQuantumWideClass % kQuantumWide == 0, 94 "kMaxQuantumWideClass is not a multiple of kQuantumWide"); 95 static_assert(kQuantum < kQuantumWide, 96 "kQuantum must be smaller than kQuantumWide"); 97 static_assert(mozilla::IsPowerOfTwo(kMinSubPageClass), 98 "kMinSubPageClass is not a power of two"); 99 100 // Number of quantum-spaced classes. We add kQuantum(Max) before subtracting to 101 // avoid underflow when a class is empty (Max<Min). 102 static constexpr size_t kNumQuantumClasses = 103 (kMaxQuantumClass + kQuantum - kMinQuantumClass) / kQuantum; 104 static constexpr size_t kNumQuantumWideClasses = 105 (kMaxQuantumWideClass + kQuantumWide - kMinQuantumWideClass) / kQuantumWide; 106 107 // Size and alignment of memory chunks that are allocated by the OS's virtual 108 // memory system. 109 static constexpr size_t kChunkSize = 1_MiB; 110 static constexpr size_t kChunkSizeMask = kChunkSize - 1; 111 112 // Maximum size of L1 cache line. This is used to avoid cache line aliasing, 113 // so over-estimates are okay (up to a point), but under-estimates will 114 // negatively affect performance. 115 constexpr size_t kCacheLineSize = 116 #if defined(XP_DARWIN) && defined(__aarch64__) 117 128 118 #else 119 64 120 #endif 121 ; 122 123 // Recycle at most 128 MiB of chunks. This means we retain at most 124 // 6.25% of the process address space on a 32-bit OS for later use. 125 static constexpr size_t gRecycleLimit = 128_MiB; 126 127 #endif /* ! CONSTANTS_H */