partition_alloc_config.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_
  5. #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_
  6. #include "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h"
  7. #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
  8. #include "build/build_config.h"
  9. // ARCH_CPU_64_BITS implies 64-bit instruction set, but not necessarily 64-bit
  10. // address space. The only known case where address space is 32-bit is NaCl, so
  11. // eliminate it explicitly. static_assert below ensures that others won't slip
  12. // through.
  13. #if defined(ARCH_CPU_64_BITS) && !BUILDFLAG(IS_NACL)
  14. #define PA_HAS_64_BITS_POINTERS
  15. static_assert(sizeof(void*) == 8, "");
  16. #else
  17. static_assert(sizeof(void*) != 8, "");
  18. #endif // defined(ARCH_CPU_64_BITS) && !BUILDFLAG(IS_NACL)
  19. // PCScan supports 64 bits only.
  20. #if defined(PA_HAS_64_BITS_POINTERS)
  21. #define PA_ALLOW_PCSCAN
  22. #endif
  23. #if defined(PA_HAS_64_BITS_POINTERS) && \
  24. (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FP)
  25. #define PA_STARSCAN_NEON_SUPPORTED
  26. #endif
  27. #if defined(PA_HAS_64_BITS_POINTERS) && (BUILDFLAG(IS_IOS) || BUILDFLAG(IS_WIN))
  28. // Use dynamically sized GigaCage. This allows to query the size at run-time,
  29. // before initialization, instead of using a hardcoded constexpr.
  30. //
  31. // This is needed on iOS because iOS test processes can't handle a large cage
  32. // (see crbug.com/1250788).
  33. //
  34. // This is needed on Windows, because OS versions <8.1 incur commit charge even
  35. // on reserved address space, thus don't handle large cage well (see
  36. // crbug.com/1101421 and crbug.com/1217759).
  37. //
  38. // This setting is specific to 64-bit, as 32-bit has a different implementation.
  39. #define PA_USE_DYNAMICALLY_SIZED_GIGA_CAGE
  40. #endif // defined(PA_HAS_64_BITS_POINTERS) &&
  41. // (BUILDFLAG(IS_IOS) || BUILDFLAG(IS_WIN))
  42. #if defined(PA_HAS_64_BITS_POINTERS) && \
  43. (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
  44. #include <linux/version.h>
  45. // TODO(bikineev): Enable for ChromeOS.
  46. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
  47. #define PA_STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED
  48. #endif
  49. #endif // defined(PA_HAS_64_BITS_POINTERS) &&
  50. // (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
  51. #if defined(PA_HAS_64_BITS_POINTERS)
  52. // Use card table to avoid races for PCScan configuration without safepoints.
  53. // The card table provides the guaranteee that for a marked card the underling
  54. // super-page is fully initialized.
  55. #define PA_STARSCAN_USE_CARD_TABLE 1
  56. #else
  57. // The card table is permanently disabled for 32-bit.
  58. #define PA_STARSCAN_USE_CARD_TABLE 0
  59. #endif // defined(PA_HAS_64_BITS_POINTERS)
  60. #if PA_STARSCAN_USE_CARD_TABLE && !defined(PA_ALLOW_PCSCAN)
  61. #error "Card table can only be used when *Scan is allowed"
  62. #endif
  63. // Use batched freeing when sweeping pages. This builds up a freelist in the
  64. // scanner thread and appends to the slot-span's freelist only once.
  65. #define PA_STARSCAN_BATCHED_FREE 1
  66. // POSIX is not only UNIX, e.g. macOS and other OSes. We do use Linux-specific
  67. // features such as futex(2).
  68. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  69. #define PA_HAS_LINUX_KERNEL
  70. #endif
  71. // On some platforms, we implement locking by spinning in userspace, then going
  72. // into the kernel only if there is contention. This requires platform support,
  73. // namely:
  74. // - On Linux, futex(2)
  75. // - On Windows, a fast userspace "try" operation which is available
  76. // with SRWLock
  77. // - On macOS, pthread_mutex_trylock() is fast by default starting with macOS
  78. // 10.14. Chromium targets an earlier version, so it cannot be known at
  79. // compile-time. So we use something different.
  80. // - Otherwise, on POSIX we assume that a fast userspace pthread_mutex_trylock()
  81. // is available.
  82. //
  83. // Otherwise, a userspace spinlock implementation is used.
  84. #if defined(PA_HAS_LINUX_KERNEL) || BUILDFLAG(IS_WIN) || \
  85. BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  86. #define PA_HAS_FAST_MUTEX
  87. #endif
  88. // If defined, enables zeroing memory on Free() with roughly 1% probability.
  89. // This applies only to normal buckets, as direct-map allocations are always
  90. // decommitted.
  91. // TODO(bartekn): Re-enable once PartitionAlloc-Everywhere evaluation is done.
  92. #if 0
  93. #define PA_ZERO_RANDOMLY_ON_FREE
  94. #endif
  95. // Need TLS support.
  96. #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
  97. #define PA_THREAD_CACHE_SUPPORTED
  98. #endif
  99. // Too expensive for official builds, as it adds cache misses to all
  100. // allocations. On the other hand, we want wide metrics coverage to get
  101. // realistic profiles.
  102. #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && !defined(OFFICIAL_BUILD)
  103. #define PA_THREAD_CACHE_ALLOC_STATS
  104. #endif
  105. // Optional statistics collection. Lightweight, contrary to the ones above,
  106. // hence enabled by default.
  107. #define PA_THREAD_CACHE_ENABLE_STATISTICS
  108. // Enable free list shadow entry to strengthen hardening as much as possible.
  109. // The shadow entry is an inversion (bitwise-NOT) of the encoded `next` pointer.
  110. //
  111. // Disabled when ref-count is placed in the previous slot, as it will overlap
  112. // with the shadow for the smallest slots.
  113. //
  114. // Disabled on Big Endian CPUs, because encoding is also a bitwise-NOT there,
  115. // making the shadow entry equal to the original, valid pointer to the next
  116. // slot. In case Use-after-Free happens, we'd rather not hand out a valid,
  117. // ready-to-use pointer.
  118. #if !BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) && \
  119. defined(ARCH_CPU_LITTLE_ENDIAN)
  120. #define PA_HAS_FREELIST_SHADOW_ENTRY
  121. #endif
  122. // Specifies whether allocation extras need to be added.
  123. #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(USE_BACKUP_REF_PTR)
  124. #define PA_EXTRAS_REQUIRED
  125. #endif
  126. // Count and total wall clock time spent in memory related system calls. This
  127. // doesn't cover all system calls, in particular the ones related to locking.
  128. //
  129. // Not enabled by default, as it has a runtime cost, and causes issues with some
  130. // builds (e.g. Windows).
  131. // However the total count is collected on all platforms.
  132. // #define PA_COUNT_SYSCALL_TIME
  133. // On Windows, |thread_local| variables cannot be marked "dllexport", see
  134. // compiler error C2492 at
  135. // https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2492?view=msvc-160.
  136. // Don't use it there.
  137. //
  138. // On macOS and iOS:
  139. // - With PartitionAlloc-Everywhere, thread_local allocates, reentering the
  140. // allocator.
  141. // - Component builds triggered a clang bug: crbug.com/1243375
  142. //
  143. // Regardless, the "normal" TLS access is fast on x86_64 (see partition_tls.h),
  144. // so don't bother with thread_local anywhere.
  145. #if !(BUILDFLAG(IS_WIN) && defined(COMPONENT_BUILD)) && !BUILDFLAG(IS_APPLE)
  146. #define PA_THREAD_LOCAL_TLS
  147. #endif
  148. // When PartitionAlloc is malloc(), detect malloc() becoming re-entrant by
  149. // calling malloc() again.
  150. //
  151. // Limitations:
  152. // - BUILDFLAG(PA_DCHECK_IS_ON) due to runtime cost
  153. // - thread_local TLS to simplify the implementation
  154. // - Not on Android due to bot failures
  155. #if BUILDFLAG(PA_DCHECK_IS_ON) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \
  156. defined(PA_THREAD_LOCAL_TLS) && !BUILDFLAG(IS_ANDROID)
  157. #define PA_HAS_ALLOCATION_GUARD
  158. #endif
  159. #if defined(ARCH_CPU_ARM64) && defined(__clang__) && \
  160. (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
  161. static_assert(sizeof(void*) == 8);
  162. #define PA_HAS_MEMORY_TAGGING
  163. #endif
  164. // Lazy commit should only be enabled on Windows, because commit charge is
  165. // only meaningful and limited on Windows. It affects performance on other
  166. // platforms and is simply not needed there due to OS supporting overcommit.
  167. #if BUILDFLAG(IS_WIN)
  168. constexpr bool kUseLazyCommit = true;
  169. #else
  170. constexpr bool kUseLazyCommit = false;
  171. #endif
  172. // On these platforms, lock all the partitions before fork(), and unlock after.
  173. // This may be required on more platforms in the future.
  174. #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  175. #define PA_HAS_ATFORK_HANDLER
  176. #endif
  177. // PartitionAlloc uses PartitionRootEnumerator to acquire all
  178. // PartitionRoots at BeforeFork and to release at AfterFork.
  179. #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && defined(PA_HAS_ATFORK_HANDLER)
  180. #define PA_USE_PARTITION_ROOT_ENUMERATOR
  181. #endif
  182. // Due to potential conflict with the free list pointer in the "previous slot"
  183. // mode in the smallest bucket, we can't check both the cookie and the dangling
  184. // raw_ptr at the same time.
  185. #if !(BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS) && \
  186. BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)) && \
  187. (BUILDFLAG(PA_DCHECK_IS_ON) || \
  188. BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS))
  189. #define PA_REF_COUNT_CHECK_COOKIE
  190. #endif
  191. // Use available space in the reference count to store the initially requested
  192. // size from the application. This is used for debugging, hence disabled by
  193. // default.
  194. // #define PA_REF_COUNT_STORE_REQUESTED_SIZE
  195. #if defined(PA_REF_COUNT_STORE_REQUESTED_SIZE) && \
  196. defined(PA_REF_COUNT_CHECK_COOKIE)
  197. #error "Cannot use a cookie *and* store the allocation size"
  198. #endif
  199. // Prefer smaller slot spans.
  200. //
  201. // Smaller slot spans may improve dirty memory fragmentation, but may also
  202. // increase address space usage.
  203. //
  204. // This is intended to roll out more broadly, but only enabled on Linux for now
  205. // to get performance bot and real-world data pre-A/B experiment.
  206. //
  207. // Also enabled on ARM64 macOS, as the 16kiB pages on this platform lead to
  208. // larger slot spans.
  209. #if BUILDFLAG(IS_LINUX) || (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64))
  210. #define PA_PREFER_SMALLER_SLOT_SPANS
  211. #endif // BUILDFLAG(IS_LINUX) || (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64))
  212. // Build MTECheckedPtr code.
  213. //
  214. // Only applicable to code with 64-bit pointers. Currently conflicts with true
  215. // hardware MTE.
  216. #if BUILDFLAG(USE_MTE_CHECKED_PTR) && defined(PA_HAS_64_BITS_POINTERS) && \
  217. !defined(PA_HAS_MEMORY_TAGGING)
  218. #define PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS
  219. #endif // BUILDFLAG(USE_MTE_CHECKED_PTR) && defined(PA_HAS_64_BITS_POINTERS) &&
  220. // !defined(PA_HAS_MEMORY_TAGGING)
  221. #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_