123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_
- #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_
- #include "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h"
- #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
- #include "build/build_config.h"
- // ARCH_CPU_64_BITS implies 64-bit instruction set, but not necessarily 64-bit
- // address space. The only known case where address space is 32-bit is NaCl, so
- // eliminate it explicitly. static_assert below ensures that others won't slip
- // through.
- #if defined(ARCH_CPU_64_BITS) && !BUILDFLAG(IS_NACL)
- #define PA_HAS_64_BITS_POINTERS
- static_assert(sizeof(void*) == 8, "");
- #else
- static_assert(sizeof(void*) != 8, "");
- #endif // defined(ARCH_CPU_64_BITS) && !BUILDFLAG(IS_NACL)
- // PCScan supports 64 bits only.
- #if defined(PA_HAS_64_BITS_POINTERS)
- #define PA_ALLOW_PCSCAN
- #endif
- #if defined(PA_HAS_64_BITS_POINTERS) && \
- (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FP)
- #define PA_STARSCAN_NEON_SUPPORTED
- #endif
- #if defined(PA_HAS_64_BITS_POINTERS) && (BUILDFLAG(IS_IOS) || BUILDFLAG(IS_WIN))
- // Use dynamically sized GigaCage. This allows to query the size at run-time,
- // before initialization, instead of using a hardcoded constexpr.
- //
- // This is needed on iOS because iOS test processes can't handle a large cage
- // (see crbug.com/1250788).
- //
- // This is needed on Windows, because OS versions <8.1 incur commit charge even
- // on reserved address space, thus don't handle large cage well (see
- // crbug.com/1101421 and crbug.com/1217759).
- //
- // This setting is specific to 64-bit, as 32-bit has a different implementation.
- #define PA_USE_DYNAMICALLY_SIZED_GIGA_CAGE
- #endif // defined(PA_HAS_64_BITS_POINTERS) &&
- // (BUILDFLAG(IS_IOS) || BUILDFLAG(IS_WIN))
- #if defined(PA_HAS_64_BITS_POINTERS) && \
- (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
- #include <linux/version.h>
- // TODO(bikineev): Enable for ChromeOS.
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
- #define PA_STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED
- #endif
- #endif // defined(PA_HAS_64_BITS_POINTERS) &&
- // (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
- #if defined(PA_HAS_64_BITS_POINTERS)
- // Use card table to avoid races for PCScan configuration without safepoints.
- // The card table provides the guaranteee that for a marked card the underling
- // super-page is fully initialized.
- #define PA_STARSCAN_USE_CARD_TABLE 1
- #else
- // The card table is permanently disabled for 32-bit.
- #define PA_STARSCAN_USE_CARD_TABLE 0
- #endif // defined(PA_HAS_64_BITS_POINTERS)
- #if PA_STARSCAN_USE_CARD_TABLE && !defined(PA_ALLOW_PCSCAN)
- #error "Card table can only be used when *Scan is allowed"
- #endif
- // Use batched freeing when sweeping pages. This builds up a freelist in the
- // scanner thread and appends to the slot-span's freelist only once.
- #define PA_STARSCAN_BATCHED_FREE 1
- // POSIX is not only UNIX, e.g. macOS and other OSes. We do use Linux-specific
- // features such as futex(2).
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
- #define PA_HAS_LINUX_KERNEL
- #endif
- // On some platforms, we implement locking by spinning in userspace, then going
- // into the kernel only if there is contention. This requires platform support,
- // namely:
- // - On Linux, futex(2)
- // - On Windows, a fast userspace "try" operation which is available
- // with SRWLock
- // - On macOS, pthread_mutex_trylock() is fast by default starting with macOS
- // 10.14. Chromium targets an earlier version, so it cannot be known at
- // compile-time. So we use something different.
- // - Otherwise, on POSIX we assume that a fast userspace pthread_mutex_trylock()
- // is available.
- //
- // Otherwise, a userspace spinlock implementation is used.
- #if defined(PA_HAS_LINUX_KERNEL) || BUILDFLAG(IS_WIN) || \
- BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- #define PA_HAS_FAST_MUTEX
- #endif
- // If defined, enables zeroing memory on Free() with roughly 1% probability.
- // This applies only to normal buckets, as direct-map allocations are always
- // decommitted.
- // TODO(bartekn): Re-enable once PartitionAlloc-Everywhere evaluation is done.
- #if 0
- #define PA_ZERO_RANDOMLY_ON_FREE
- #endif
- // Need TLS support.
- #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
- #define PA_THREAD_CACHE_SUPPORTED
- #endif
- // Too expensive for official builds, as it adds cache misses to all
- // allocations. On the other hand, we want wide metrics coverage to get
- // realistic profiles.
- #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && !defined(OFFICIAL_BUILD)
- #define PA_THREAD_CACHE_ALLOC_STATS
- #endif
- // Optional statistics collection. Lightweight, contrary to the ones above,
- // hence enabled by default.
- #define PA_THREAD_CACHE_ENABLE_STATISTICS
- // Enable free list shadow entry to strengthen hardening as much as possible.
- // The shadow entry is an inversion (bitwise-NOT) of the encoded `next` pointer.
- //
- // Disabled when ref-count is placed in the previous slot, as it will overlap
- // with the shadow for the smallest slots.
- //
- // Disabled on Big Endian CPUs, because encoding is also a bitwise-NOT there,
- // making the shadow entry equal to the original, valid pointer to the next
- // slot. In case Use-after-Free happens, we'd rather not hand out a valid,
- // ready-to-use pointer.
- #if !BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) && \
- defined(ARCH_CPU_LITTLE_ENDIAN)
- #define PA_HAS_FREELIST_SHADOW_ENTRY
- #endif
- // Specifies whether allocation extras need to be added.
- #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(USE_BACKUP_REF_PTR)
- #define PA_EXTRAS_REQUIRED
- #endif
- // Count and total wall clock time spent in memory related system calls. This
- // doesn't cover all system calls, in particular the ones related to locking.
- //
- // Not enabled by default, as it has a runtime cost, and causes issues with some
- // builds (e.g. Windows).
- // However the total count is collected on all platforms.
- // #define PA_COUNT_SYSCALL_TIME
- // On Windows, |thread_local| variables cannot be marked "dllexport", see
- // compiler error C2492 at
- // https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2492?view=msvc-160.
- // Don't use it there.
- //
- // On macOS and iOS:
- // - With PartitionAlloc-Everywhere, thread_local allocates, reentering the
- // allocator.
- // - Component builds triggered a clang bug: crbug.com/1243375
- //
- // Regardless, the "normal" TLS access is fast on x86_64 (see partition_tls.h),
- // so don't bother with thread_local anywhere.
- #if !(BUILDFLAG(IS_WIN) && defined(COMPONENT_BUILD)) && !BUILDFLAG(IS_APPLE)
- #define PA_THREAD_LOCAL_TLS
- #endif
- // When PartitionAlloc is malloc(), detect malloc() becoming re-entrant by
- // calling malloc() again.
- //
- // Limitations:
- // - BUILDFLAG(PA_DCHECK_IS_ON) due to runtime cost
- // - thread_local TLS to simplify the implementation
- // - Not on Android due to bot failures
- #if BUILDFLAG(PA_DCHECK_IS_ON) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \
- defined(PA_THREAD_LOCAL_TLS) && !BUILDFLAG(IS_ANDROID)
- #define PA_HAS_ALLOCATION_GUARD
- #endif
- #if defined(ARCH_CPU_ARM64) && defined(__clang__) && \
- (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
- static_assert(sizeof(void*) == 8);
- #define PA_HAS_MEMORY_TAGGING
- #endif
- // Lazy commit should only be enabled on Windows, because commit charge is
- // only meaningful and limited on Windows. It affects performance on other
- // platforms and is simply not needed there due to OS supporting overcommit.
- #if BUILDFLAG(IS_WIN)
- constexpr bool kUseLazyCommit = true;
- #else
- constexpr bool kUseLazyCommit = false;
- #endif
- // On these platforms, lock all the partitions before fork(), and unlock after.
- // This may be required on more platforms in the future.
- #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- #define PA_HAS_ATFORK_HANDLER
- #endif
- // PartitionAlloc uses PartitionRootEnumerator to acquire all
- // PartitionRoots at BeforeFork and to release at AfterFork.
- #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && defined(PA_HAS_ATFORK_HANDLER)
- #define PA_USE_PARTITION_ROOT_ENUMERATOR
- #endif
- // Due to potential conflict with the free list pointer in the "previous slot"
- // mode in the smallest bucket, we can't check both the cookie and the dangling
- // raw_ptr at the same time.
- #if !(BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS) && \
- BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)) && \
- (BUILDFLAG(PA_DCHECK_IS_ON) || \
- BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS))
- #define PA_REF_COUNT_CHECK_COOKIE
- #endif
- // Use available space in the reference count to store the initially requested
- // size from the application. This is used for debugging, hence disabled by
- // default.
- // #define PA_REF_COUNT_STORE_REQUESTED_SIZE
- #if defined(PA_REF_COUNT_STORE_REQUESTED_SIZE) && \
- defined(PA_REF_COUNT_CHECK_COOKIE)
- #error "Cannot use a cookie *and* store the allocation size"
- #endif
- // Prefer smaller slot spans.
- //
- // Smaller slot spans may improve dirty memory fragmentation, but may also
- // increase address space usage.
- //
- // This is intended to roll out more broadly, but only enabled on Linux for now
- // to get performance bot and real-world data pre-A/B experiment.
- //
- // Also enabled on ARM64 macOS, as the 16kiB pages on this platform lead to
- // larger slot spans.
- #if BUILDFLAG(IS_LINUX) || (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64))
- #define PA_PREFER_SMALLER_SLOT_SPANS
- #endif // BUILDFLAG(IS_LINUX) || (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64))
- // Build MTECheckedPtr code.
- //
- // Only applicable to code with 64-bit pointers. Currently conflicts with true
- // hardware MTE.
- #if BUILDFLAG(USE_MTE_CHECKED_PTR) && defined(PA_HAS_64_BITS_POINTERS) && \
- !defined(PA_HAS_MEMORY_TAGGING)
- #define PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS
- #endif // BUILDFLAG(USE_MTE_CHECKED_PTR) && defined(PA_HAS_64_BITS_POINTERS) &&
- // !defined(PA_HAS_MEMORY_TAGGING)
- #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CONFIG_H_
|