tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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