Update On Sat Jul 27 20:32:02 CEST 2024

This commit is contained in:
github-action[bot]
2024-07-27 20:32:03 +02:00
parent a937fef22b
commit 598868ca17
1750 changed files with 27809 additions and 17985 deletions
+1 -1
View File
@@ -1 +1 @@
126.0.6478.40
127.0.6533.64
+1 -1
View File
@@ -59,7 +59,7 @@ Options:
PROXY = PROXY-CHAIN | SOCKS-PROXY
PROXY-CHAIN = <PROXY-URI>[","<PROXY-CHAIN>]
PROXY-URI = <PROXY-PROTO>"://"<USER>":"<PASS>"@"<HOSTNAME>[":"<PORT>]
PROXY-URI = <PROXY-PROTO>"://"[<USER>":"<PASS>"@"]<HOSTNAME>[":"<PORT>]
PROXY-PROTO = "http" | "https" | "quic"
SOCKS-PROXY = "socks://"<HOSTNAME>[":"<PORT>]
+7 -4
View File
@@ -55,11 +55,14 @@ default_args = {
crashpad_dependencies = "chromium"
# Override ANGLE's Vulkan dependencies.
angle_vulkan_headers_dir = "//third_party/vulkan-deps/vulkan-headers/src"
angle_vulkan_loader_dir = "//third_party/vulkan-deps/vulkan-loader/src"
angle_vulkan_tools_dir = "//third_party/vulkan-deps/vulkan-tools/src"
angle_vulkan_headers_dir = "//third_party/vulkan-headers/src"
angle_vulkan_loader_dir = "//third_party/vulkan-loader/src"
angle_vulkan_tools_dir = "//third_party/vulkan-tools/src"
angle_vulkan_validation_layers_dir =
"//third_party/vulkan-deps/vulkan-validation-layers/src"
"//third_party/vulkan-validation-layers/src"
# Override VMA's Vulkan dependencies.
vma_vulkan_headers_dir = "//third_party/vulkan-headers/src"
# Overwrite default args declared in the Fuchsia sdk
fuchsia_sdk_readelf_exec =
+9 -1
View File
@@ -86,6 +86,7 @@ Alexey Kuts <kruntuid@gmail.com>
Alexey Kuzmin <alex.s.kuzmin@gmail.com>
Alexey Kuznetsov <saturas2000@gmail.com>
Alexey Terentiev <alexeyter@gmail.com>
Alexia Bojian <bojianalexia4@gmail.com>
Alexis Brenon <brenon.alexis@gmail.com>
Alexis La Goutte <alexis.lagoutte@gmail.com>
Alexis Menard <alexis.menard@intel.com>
@@ -376,6 +377,7 @@ Dongseong Hwang <dongseong.hwang@intel.com>
Dongwoo Joshua Im <dw.im@samsung.com>
Dongyu Lin <l2d4y3@gmail.com>
Donna Wu <donna.wu@intel.com>
Douglas Browne <douglas.browne123@gmail.com>
Douglas F. Turner <doug.turner@gmail.com>
Drew Blaisdell <drew.blaisdell@gmail.com>
Dushyant Kant Sharma <dush.sharma@samsung.com>
@@ -400,6 +402,7 @@ Emil Suleymanov <emil@esnx.xyz>
Ergun Erdogmus <erdogmusergun@gmail.com>
Eric Ahn <byungwook.ahn@gmail.com>
Eric Huang <ele828@gmail.com>
Eric Long <i@hack3r.moe>
Eric Rescorla <ekr@rtfm.com>
Erik Hill <erikghill@gmail.com>
Erik Kurzinger <ekurzinger@gmail.com>
@@ -656,8 +659,8 @@ Jincheol Jo <jincheol.jo@navercorp.com>
Jinfeng Ma <majinfeng1@xiaomi.com>
Jing Zhao <zhaojing7@xiaomi.com>
Jinglong Zuo <zuojinglong@xiaomi.com>
Jingqi Sun <sunjingqi47@gmail.com>
Jingqi Sun <jingqi.sun@hotmail.com>
Jingqi Sun <sunjingqi47@gmail.com>
Jingwei Liu <kingweiliu@gmail.com>
Jingyi Wei <wjywbs@gmail.com>
Jinho Bang <jinho.bang@samsung.com>
@@ -768,6 +771,7 @@ Keita Suzuki <keitasuzuki.park@gmail.com>
Keita Yoshimoto <y073k3@gmail.com>
Keith Chen <keitchen@amazon.com>
Keith Cirkel <chromium@keithcirkel.co.uk>
Kelsen Liu <kelsenliu21@gmail.com>
Kenneth Rohde Christiansen <kenneth.r.christiansen@intel.com>
Kenneth Strickland <ken.strickland@gmail.com>
Kenneth Zhou <knthzh@gmail.com>
@@ -816,6 +820,7 @@ Lalit Chandivade <lalit.chandivade@einfochips.com>
Lam Lu <lamlu@amazon.com>
Laszlo Gombos <l.gombos@samsung.com>
Laszlo Radanyi <bekkra@gmail.com>
lauren n. liberda <lauren@selfisekai.rocks>
Lauren Yeun Kim <lauren.yeun.kim@gmail.com>
Lauri Oherd <lauri.oherd@gmail.com>
Lavar Askew <open.hyperion@gmail.com>
@@ -1242,6 +1247,7 @@ Sean Bryant <sean@cyberwang.net>
Sean DuBois <seaduboi@amazon.com>
Sebastian Amend <sebastian.amend@googlemail.com>
Sebastian Krzyszkowiak <dos@dosowisko.net>
Sebastian Markbåge <sebastian@calyptus.eu>
Sebastjan Raspor <sebastjan.raspor1@gmail.com>
Seo Sanghyeon <sanxiyn@gmail.com>
Seokju Kwon <seokju.kwon@gmail.com>
@@ -1394,6 +1400,7 @@ Thomas Nguyen <haitung.nguyen@avast.com>
Thomas Phillips <tphillips@snapchat.com>
Thomas White <im.toms.inbox@gmail.com>
Tiago Vignatti <tiago.vignatti@intel.com>
Tianyi Zhang <me@1stprinciple.org>
Tibor Dusnoki <tibor.dusnoki.91@gmail.com>
Tibor Dusnoki <tdusnoki@inf.u-szeged.hu>
Tien Hock Loh <tienhock.loh@starfivetech.com>
@@ -1416,6 +1423,7 @@ Tony Shen <legendmastertony@gmail.com>
Torsten Kurbad <google@tk-webart.de>
Toshihito Kikuchi <leamovret@gmail.com>
Toshiaki Tanaka <zokutyou2@gmail.com>
Travis Leithead <travis.leithead@gmail.com>
Trent Willis <trentmwillis@gmail.com>
Trevor Perrin <unsafe@trevp.net>
Tripta Gupta <triptagupta19@gmail.com>
+494 -265
View File
File diff suppressed because it is too large Load Diff
+8 -48
View File
@@ -92,14 +92,6 @@ assert(!is_nacl || is_nacl_saigo,
assert(!is_win || is_clang,
"only clang-cl is supported on Windows, see https://crbug.com/988071")
# Whether we should provide a `__libcpp_verbose_abort` handler that discards
# `__VA_ARGS__` and just calls base::ImmediateCrash() for hardening failures.
# This conditional matches `defined(OFFICIAL_BUILD) && !DCHECK_IS_ON()` in
# base/check.h. I.e. we optimize `::std::__libcpp_verbose_abort(__VA_ARGS__)`
# to discard `__VA_ARGS__` when we disable logging from CHECK() failures.
use_nodebug_assertion =
use_custom_libcxx && is_official_build && !is_debug && !dcheck_always_on
# Determines whether libevent should be dep.
dep_libevent = !is_fuchsia && !is_win && !is_mac && !is_nacl
@@ -176,16 +168,6 @@ if (is_fuchsia) {
}
}
config("perfetto_config") {
if (use_perfetto_client_library) {
defines = [
# Use TRACE_EVENT macro implementation from Perfetto. See
# trace_event/trace_event_common.h.
"BASE_USE_PERFETTO_CLIENT_LIBRARY=1",
]
}
}
if (enable_pkeys && is_debug) {
config("no_stack_protector") {
cflags = [ "-fno-stack-protector" ]
@@ -682,6 +664,7 @@ component("base") {
"synchronization/lock.cc",
"synchronization/lock.h",
"synchronization/lock_impl.h",
"synchronization/lock_subtle.h",
"synchronization/waitable_event.cc",
"synchronization/waitable_event.h",
"synchronization/waitable_event_watcher.h",
@@ -1073,13 +1056,11 @@ component("base") {
":check_version_internal",
":message_pump_buildflags",
"//base/allocator:buildflags",
"//base/allocator/partition_allocator:raw_ptr",
"//base/third_party/double_conversion",
"//build:blink_buildflags",
"//build:branding_buildflags",
"//build:ios_buildflags",
"//build/config/compiler:compiler_buildflags",
"//third_party/abseil-cpp:absl",
"//third_party/modp_b64",
]
@@ -1133,10 +1114,6 @@ component("base") {
public_deps += [ "//build/rust:cxx_cppdeps" ]
}
if (use_nodebug_assertion) {
public_deps += [ ":nodebug_assertion" ]
}
# Needed for <atomic> if using newer C++ library than sysroot, except if
# building inside the cros_sdk environment - use host_toolchain as a
# more robust check for this.
@@ -1282,7 +1259,6 @@ component("base") {
"android/jni_array.h",
"android/jni_bytebuffer.cc",
"android/jni_bytebuffer.h",
"android/jni_conversions.cc",
"android/jni_registrar.cc",
"android/jni_registrar.h",
"android/jni_string.cc",
@@ -2373,24 +2349,17 @@ component("base") {
"//third_party/perfetto/include/perfetto/protozero",
]
all_dependent_configs += [
":perfetto_config",
"//third_party/perfetto/gn:public_config",
]
all_dependent_configs += [ "//third_party/perfetto/gn:public_config" ]
if (is_win) {
sources += [
"trace_event/etw_interceptor_win.cc",
"trace_event/etw_interceptor_win.h",
"trace_event/trace_event_etw_export_win.cc",
"trace_event/trace_event_etw_export_win.h",
"trace_event/trace_logging_minimal_win.cc",
"trace_event/trace_logging_minimal_win.h",
]
if (use_perfetto_client_library) {
sources += [
"trace_event/etw_interceptor_win.cc",
"trace_event/etw_interceptor_win.h",
]
}
}
if (is_android) {
@@ -2489,6 +2458,8 @@ buildflag_header("debugging_buildflags") {
symbol_level > 0,
"symbol_level must be set to greater than 0 for source line numbers.")
}
_enable_stack_trace_line_numbers =
!print_unsymbolized_stack_traces && enable_stack_trace_line_numbers
flags = [
"DCHECK_IS_CONFIGURABLE=$dcheck_is_configurable",
@@ -2500,10 +2471,11 @@ buildflag_header("debugging_buildflags") {
"ENABLE_GDBINIT_WARNING=$enable_gdbinit_warning",
"ENABLE_LLDBINIT_WARNING=$enable_lldbinit_warning",
"EXPENSIVE_DCHECKS_ARE_ON=$enable_expensive_dchecks",
"ENABLE_STACK_TRACE_LINE_NUMBERS=$enable_stack_trace_line_numbers",
"ENABLE_STACK_TRACE_LINE_NUMBERS=$_enable_stack_trace_line_numbers",
"ENABLE_COMMANDLINE_SEQUENCE_CHECKS=$enable_commandline_sequence_checks",
"ENABLE_ALLOCATION_STACK_TRACE_RECORDER=$build_allocation_stack_trace_recorder",
"ENABLE_ALLOCATION_TRACE_RECORDER_FULL_REPORTING=$build_allocation_trace_recorder_full_reporting",
"PRINT_UNSYMBOLIZED_STACK_TRACES=$print_unsymbolized_stack_traces",
]
}
@@ -2597,7 +2569,6 @@ buildflag_header("tracing_buildflags") {
flags = [
"ENABLE_BASE_TRACING=$enable_base_tracing",
"USE_PERFETTO_CLIENT_LIBRARY=$use_perfetto_client_library",
"USE_PERFETTO_TRACE_PROCESSOR=$use_perfetto_trace_processor",
"OPTIONAL_TRACE_EVENTS_ENABLED=$optional_trace_events_enabled",
]
@@ -2663,17 +2634,6 @@ static_library("base_static") {
}
}
if (use_nodebug_assertion) {
# nodebug_assertion.cc has to be in its own source_set instead of being
# included as a source in //base as otherwise its symbols won't be linked in
# if they end up in an archive.
source_set("nodebug_assertion") {
defines = [ "BASE_IMPLEMENTATION" ]
sources = [ "nodebug_assertion.cc" ]
deps = [ ":base_static" ]
}
}
action("build_date") {
script = "write_build_date_header.py"
+1 -1
View File
@@ -43,7 +43,7 @@ specific_include_rules = {
"+third_party/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h",
],
# To evaluate the performance effects of using absl's flat_hash_map.
"supports_user_data\.h": [
"supports_user_data\.cc": [
"+third_party/abseil-cpp/absl/container/flat_hash_map.h",
]
}
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_ALLOCATOR_DISPATCHER_TAGGING_H_
#define BASE_ALLOCATOR_DISPATCHER_TAGGING_H_
#ifndef BASE_ALLOCATOR_DISPATCHER_MEMORY_TAGGING_H_
#define BASE_ALLOCATOR_DISPATCHER_MEMORY_TAGGING_H_
#include "partition_alloc/tagging.h"
@@ -39,4 +39,4 @@ constexpr MTEMode ConvertToMTEMode(
} // namespace base::allocator::dispatcher
#endif // BASE_ALLOCATOR_DISPATCHER_TAGGING_H_
#endif // BASE_ALLOCATOR_DISPATCHER_MEMORY_TAGGING_H_
@@ -15,6 +15,7 @@
#include "build/chromeos_buildflags.h"
#include "partition_alloc/partition_alloc_base/time/time.h"
#include "partition_alloc/partition_alloc_buildflags.h"
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/partition_root.h"
#include "partition_alloc/shim/allocator_shim_dispatch_to_noop_on_free.h"
#include "partition_alloc/thread_cache.h"
@@ -94,21 +95,24 @@ BASE_FEATURE(kPartitionAllocLargeThreadCacheSize,
"PartitionAllocLargeThreadCacheSize",
FEATURE_ENABLED_BY_DEFAULT);
MIRACLE_PARAMETER_FOR_INT(
GetPartitionAllocLargeThreadCacheSizeValue,
kPartitionAllocLargeThreadCacheSize,
"PartitionAllocLargeThreadCacheSizeValue",
::partition_alloc::ThreadCacheLimits::kLargeSizeThreshold)
MIRACLE_PARAMETER_FOR_INT(GetPartitionAllocLargeThreadCacheSizeValue,
kPartitionAllocLargeThreadCacheSize,
"PartitionAllocLargeThreadCacheSizeValue",
::partition_alloc::kThreadCacheLargeSizeThreshold)
MIRACLE_PARAMETER_FOR_INT(
GetPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid,
kPartitionAllocLargeThreadCacheSize,
"PartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid",
::partition_alloc::ThreadCacheLimits::kDefaultSizeThreshold)
::partition_alloc::kThreadCacheDefaultSizeThreshold)
BASE_FEATURE(kPartitionAllocLargeEmptySlotSpanRing,
"PartitionAllocLargeEmptySlotSpanRing",
#if BUILDFLAG(IS_MAC)
FEATURE_ENABLED_BY_DEFAULT);
#else
FEATURE_DISABLED_BY_DEFAULT);
#endif
BASE_FEATURE(kPartitionAllocSchedulerLoopQuarantine,
"PartitionAllocSchedulerLoopQuarantine",
@@ -486,6 +490,14 @@ void MakeFreeNoOp(WhenFreeBecomesNoOp callsite) {
BASE_FEATURE(kPartitionAllocAdjustSizeWhenInForeground,
"PartitionAllocAdjustSizeWhenInForeground",
#if BUILDFLAG(IS_MAC)
FEATURE_ENABLED_BY_DEFAULT);
#else
FEATURE_DISABLED_BY_DEFAULT);
#endif
BASE_FEATURE(kPartitionAllocUseSmallSingleSlotSpans,
"PartitionAllocUseSmallSingleSlotSpans",
base::FEATURE_DISABLED_BY_DEFAULT);
} // namespace features
@@ -218,6 +218,12 @@ BASE_EXPORT BASE_DECLARE_FEATURE(kUsePoolOffsetFreelists);
// aggressively when in the foreground.
BASE_EXPORT BASE_DECLARE_FEATURE(kPartitionAllocAdjustSizeWhenInForeground);
// When enabled, uses a more nuanced heuristic to determine if slot
// spans can be treated as "single-slot."
//
// See also: https://crbug.com/333443437
BASE_EXPORT BASE_DECLARE_FEATURE(kPartitionAllocUseSmallSingleSlotSpans);
} // namespace features
} // namespace base
@@ -50,6 +50,7 @@
#include "partition_alloc/partition_alloc_buildflags.h"
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/partition_lock.h"
#include "partition_alloc/partition_root.h"
#include "partition_alloc/pointers/instance_tracer.h"
@@ -263,6 +264,12 @@ BASE_FEATURE(kDisableMemoryReclaimerInBackground,
"DisableMemoryReclaimerInBackground",
base::FEATURE_ENABLED_BY_DEFAULT);
// When enabled, limit the time memory reclaimer may take, returning early when
// exceeded.
BASE_FEATURE(kPartitionAllocShortMemoryReclaim,
"PartitionAllocShortMemoryReclaim",
base::FEATURE_DISABLED_BY_DEFAULT);
// static
MemoryReclaimerSupport& MemoryReclaimerSupport::Instance() {
static base::NoDestructor<MemoryReclaimerSupport> instance;
@@ -327,7 +334,11 @@ void MemoryReclaimerSupport::Run() {
{
// Micros, since memory reclaiming should typically take at most a few ms.
SCOPED_UMA_HISTOGRAM_TIMER_MICROS("Memory.PartitionAlloc.MemoryReclaim");
::partition_alloc::MemoryReclaimer::Instance()->ReclaimNormal();
if (base::FeatureList::IsEnabled(kPartitionAllocShortMemoryReclaim)) {
::partition_alloc::MemoryReclaimer::Instance()->ReclaimFast();
} else {
::partition_alloc::MemoryReclaimer::Instance()->ReclaimNormal();
}
}
MaybeScheduleTask();
@@ -453,6 +464,13 @@ namespace {
internal::PartitionLock g_stack_trace_buffer_lock;
constexpr size_t kDanglingPtrStackTraceSize =
PA_BUILDFLAG(IS_DEBUG)
? 32 // Symbolizing large stack traces can be expensive in debug
// builds. We prefer displaying a reasonably sized one instead
// of timing out.
: base::debug::StackTrace::kMaxTraces;
struct DanglingPointerFreeInfo {
debug::StackTrace stack_trace;
debug::TaskTrace task_trace;
@@ -475,7 +493,11 @@ void DanglingRawPtrDetected(uintptr_t id) {
for (std::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
if (!entry) {
entry = {debug::StackTrace(), debug::TaskTrace(), id};
entry = {
debug::StackTrace(kDanglingPtrStackTraceSize),
debug::TaskTrace(),
id,
};
return;
}
}
@@ -633,7 +655,8 @@ void DanglingRawPtrReleased(uintptr_t id) {
// This is called from raw_ptr<>'s release operation. Making allocations is
// allowed. In particular, symbolizing and printing the StackTraces may
// allocate memory.
debug::StackTrace stack_trace_release;
debug::StackTrace stack_trace_release(kDanglingPtrStackTraceSize);
debug::TaskTrace task_trace_release;
std::optional<DanglingPointerFreeInfo> free_info =
TakeDanglingPointerFreeInfo(id);
@@ -1236,6 +1259,10 @@ void PartitionAllocSupport::ReconfigureAfterFeatureListInit(
partition_alloc::TagViolationReportingMode::kDisabled));
}
allocator_shim::UseSmallSingleSlotSpans use_small_single_slot_spans(
base::FeatureList::IsEnabled(
features::kPartitionAllocUseSmallSingleSlotSpans));
allocator_shim::ConfigurePartitions(
allocator_shim::EnableBrp(brp_config.enable_brp),
allocator_shim::EnableMemoryTagging(enable_memory_tagging),
@@ -1243,7 +1270,8 @@ void PartitionAllocSupport::ReconfigureAfterFeatureListInit(
allocator_shim::SchedulerLoopQuarantine(scheduler_loop_quarantine),
scheduler_loop_quarantine_branch_capacity_in_bytes,
allocator_shim::ZappingByFreeFlags(zapping_by_free_flags),
allocator_shim::UsePoolOffsetFreelists(use_pool_offset_freelists));
allocator_shim::UsePoolOffsetFreelists(use_pool_offset_freelists),
use_small_single_slot_spans);
const uint32_t extras_size = allocator_shim::GetMainPartitionRootExtrasSize();
// As per description, extras are optional and are expected not to
@@ -1442,6 +1470,9 @@ void PartitionAllocSupport::ReconfigureAfterTaskRunnerInit(
void PartitionAllocSupport::OnForegrounded(bool has_main_frame) {
#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
// Other changes are renderer-only, not this one.
MemoryReclaimerSupport::Instance().SetForegrounded(true);
{
base::AutoLock scoped_lock(lock_);
if (established_process_type_ != switches::kRendererProcess) {
@@ -1460,12 +1491,13 @@ void PartitionAllocSupport::OnForegrounded(bool has_main_frame) {
allocator_shim::AdjustDefaultAllocatorForForeground();
}
#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
MemoryReclaimerSupport::Instance().SetForegrounded(true);
}
void PartitionAllocSupport::OnBackgrounded() {
#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
// Other changes are renderer-only, not this one.
MemoryReclaimerSupport::Instance().SetForegrounded(false);
{
base::AutoLock scoped_lock(lock_);
if (established_process_type_ != switches::kRendererProcess) {
@@ -1476,7 +1508,7 @@ void PartitionAllocSupport::OnBackgrounded() {
// Performance matters less for background renderers, don't pay the memory
// cost.
::partition_alloc::ThreadCache::SetLargestCachedSize(
::partition_alloc::ThreadCacheLimits::kDefaultSizeThreshold);
::partition_alloc::kThreadCacheDefaultSizeThreshold);
// In renderers, memory reclaim uses the "idle time" task runner to run
// periodic reclaim. This does not always run when the renderer is idle, and
@@ -1499,8 +1531,6 @@ void PartitionAllocSupport::OnBackgrounded() {
allocator_shim::AdjustDefaultAllocatorForBackground();
}
#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
MemoryReclaimerSupport::Instance().SetForegrounded(false);
}
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
@@ -81,7 +81,9 @@ class BASE_EXPORT PartitionAllocSupport {
void ReconfigureAfterTaskRunnerInit(const std::string& process_type);
// |has_main_frame| tells us if the renderer contains a main frame.
void OnForegrounded(bool has_main_frame);
// The default value is intended for other process types, where the parameter
// does not make sense.
void OnForegrounded(bool has_main_frame = false);
void OnBackgrounded();
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
@@ -114,7 +116,7 @@ class BASE_EXPORT PartitionAllocSupport {
#if PA_CONFIG(THREAD_CACHE_SUPPORTED) && \
PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
size_t largest_cached_size_ =
::partition_alloc::ThreadCacheLimits::kDefaultSizeThreshold;
::partition_alloc::kThreadCacheDefaultSizeThreshold;
#endif
};
@@ -0,0 +1,8 @@
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This is partition_alloc root GN configuration. It is used when built as a
# standalone project. This is not used in production.
buildconfig = "//gn/BUILDCONFIG.gn"
@@ -36,9 +36,9 @@ specific_include_rules = {
"+testing/gmock/include/gmock/gmock.h",
"+third_party/abseil-cpp/absl/types/optional.h",
],
# TODO(https://crbug.com/1508847): Remove //build dependency.
"build_config.h$": [ "+build/build_config.h" ],
"use_death_tests\.h$": [
"+testing/gtest/include/gtest/gtest.h",
],
}
# In the context of a module-level DEPS, the `deps` variable must be defined.
@@ -9,9 +9,10 @@ for more details on the presubmit API built into depot_tools.
PRESUBMIT_VERSION = '2.0.0'
# This is the base path of the partition_alloc directory when stored inside the
# chromium repository. PRESUBMIT.py is executed from chromium.
_PARTITION_ALLOC_BASE_PATH = 'base/allocator/partition_allocator/src/'
# This is adapted from Chromium's PRESUBMIT.py. The differences are:
# - Base path: It is relative to the partition_alloc's source directory instead
# of chromium.
@@ -88,56 +89,35 @@ def CheckForIncludeGuards(input_api, output_api):
return errors
def CheckBuildConfigMacrosWithoutInclude(input_api, output_api):
# Excludes OS_CHROMEOS, which is not defined in build_config.h.
macro_re = input_api.re.compile(
r'^\s*#(el)?if.*\bdefined\(((COMPILER_|ARCH_CPU_|WCHAR_T_IS_)[^)]*)')
include_re = input_api.re.compile(
r'^#include\s+"partition_alloc/build_config.h"',
input_api.re.MULTILINE)
extension_re = input_api.re.compile(r'\.[a-z]+$')
# In .gn and .gni files, check there are no unexpected dependencies on files
# located outside of the partition_alloc repository.
#
# This is important, because partition_alloc has no CQ bots on its own, but only
# through the chromium's CQ.
#
# Only //build_overrides/ is allowed, as it provides embedders, a way to
# overrides the default build settings and forward the dependencies to
# partition_alloc.
def CheckNoExternalImportInGn(input_api, output_api):
def gn_files(file):
return file.LocalPath().endswith('.gn') or \
file.LocalPath().endswith('.gni')
# Match and capture <path> from import("<path>").
import_re = input_api.re.compile(r'^ *import\("([^"]+)"\)')
errors = []
config_h_file = input_api.os_path.join('build', 'build_config.h')
for f in input_api.AffectedFiles(include_deletes=False):
# The build-config macros are allowed to be used in build_config.h
# without including itself.
if f.LocalPath() == config_h_file:
continue
if not f.LocalPath().endswith(
('.h', '.c', '.cc', '.cpp', '.m', '.mm')):
continue
found_line_number = None
found_macro = None
all_lines = input_api.ReadFile(f, 'r').splitlines()
for line_num, line in enumerate(all_lines):
match = macro_re.search(line)
if match:
found_line_number = line_num
found_macro = match.group(2)
break
if not found_line_number:
continue
found_include_line = -1
for line_num, line in enumerate(all_lines):
if include_re.search(line):
found_include_line = line_num
break
if found_include_line >= 0 and found_include_line < found_line_number:
continue
if not f.LocalPath().endswith('.h'):
primary_header_path = extension_re.sub('.h', f.AbsoluteLocalPath())
try:
content = input_api.ReadFile(primary_header_path, 'r')
if include_re.search(content):
continue
except IOError:
pass
errors.append('%s:%d %s macro is used without first including '
'partition_alloc/build_config.h.' %
(f.LocalPath(), found_line_number, found_macro))
if errors:
return [output_api.PresubmitPromptWarning('\n'.join(errors))]
return []
for f in input_api.AffectedSourceFiles(gn_files):
for line_number, line in enumerate(input_api.ReadFile(f).splitlines()):
match = import_re.search(line)
if not match:
continue
import_path = match.group(1)
if import_path.startswith('//build_overrides/'):
continue;
if not import_path.startswith('//'):
continue;
errors.append(output_api.PresubmitError(
'%s:%d\nPartitionAlloc disallow external import: %s' %
(f.LocalPath(), line_number + 1, import_path)))
return errors;
@@ -0,0 +1,108 @@
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This is the BUILDCONFIG for building partition_alloc as a standalone project.
#
# The config is based on:
# - skia: //gn/BUILDCONFIG.gn
# - chromium: //build/config/BUILDCONFIG.gn
is_partition_alloc_standalone = true
build_with_chromium = false
is_asan = false
# It's best to keep the names and defaults of is_foo flags consistent with:
# - Chrome
# - Skia.
declare_args() {
is_official_build = false
is_component_build = false
dcheck_always_on = true
}
declare_args() {
is_debug = !is_official_build
}
# Platform detection defaults:
if (target_os == "") {
target_os = host_os
}
if (current_os == "") {
current_os = target_os
}
if (target_cpu == "") {
target_cpu = host_cpu
}
if (target_cpu == "x86_64") {
target_cpu = "x64"
}
if (current_cpu == "") {
current_cpu = target_cpu
}
is_android = current_os == "android"
is_chromeos = false
is_fuchsia = current_os == "fuchsia"
is_ios = current_os == "ios"
is_linux = current_os == "linux"
is_mac = current_os == "mac"
is_nacl = false
is_win = current_os == "win" || current_os == "winuwp"
is_cast_android = false
is_castos = false
is_chromeos_ash = false
is_cronet_build = false
enable_expensive_dchecks = false
dcheck_is_configurable = false
can_unwind_with_frame_pointers = false
is_posix = !is_win && !is_fuchsia
is_apple = is_mac || is_ios
# TODO(crbug.com/41481467): Consider expanding the standalone configuration for
# additional OSes.
assert(is_linux, "PartitionAlloc standalone only support Linux for now")
is_clang = true
# A component is either:
# - A static library (is_component_build=false)
# - A shared library (is_component_build=true)
template("component") {
if (is_component_build) {
_component_mode = "shared_library"
} else {
_component_mode = "static_library"
}
target(_component_mode, target_name) {
forward_variables_from(invoker, "*")
}
}
# Default configs
default_configs = [
"//gn/partition_alloc:default",
"//gn/partition_alloc:no_exceptions",
"//gn/partition_alloc:no_rtti",
]
if (!is_debug) {
default_configs += [
"//gn/partition_alloc:optimize",
"//gn/partition_alloc:NDEBUG",
]
}
# GCC-like toolchains, including Clang.
set_default_toolchain("//gn/toolchain:clang")
default_toolchain_name = "clang"
set_defaults("source_set") {
configs = default_configs
}
set_defaults("component") {
configs = default_configs
}
@@ -0,0 +1,2 @@
arthursonzogni@chromium.org
tasak@google.com
@@ -0,0 +1,33 @@
# PartitionAlloc standalone GN config
This directory contains a GN configuration to build partition_alloc as a
standalone library.
This is not an official product that is supported by the Chromium project. There
are no guarantees that this will work in the future, or that it will work in
all configurations. There are no commit queue or trybots using it.
This is useful for verifying that partition_alloc can be built as a library, and
discover the formal dependencies that partition_alloc has on the rest of the
Chromium project. This is not intended to be used in production code, and is not
This is also provided as a convenience for chromium developers working on
partition_alloc who want to iterate on partition_alloc without having to build
the entire Chromium project.
/!\ This is under construction. /!\
## Building
```sh
gn gen out/Default
autoninja -C out/Default
```
## Supported configurations:
### Platforms
- Linux
### Toolchains
- Clang
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Copied from Skia's //gn/cp.py
import os
import shutil
import sys
src, dst = sys.argv[1:]
if os.path.exists(dst):
if os.path.isdir(dst):
shutil.rmtree(dst)
else:
os.remove(dst)
if os.path.isdir(src):
shutil.copytree(src, dst)
else:
shutil.copy2(src, dst)
#work around https://github.com/ninja-build/ninja/issues/1554
os.utime(dst, None)
@@ -0,0 +1,45 @@
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
config("default") {
asmflags = []
cflags = []
cflags = [
"-Wno-return-type", # TODO(crbug.com/41481467): Fix this warning.
"-Wno-invalid-offsetof", # TODO(crbug.com/41481467): Fix this warning.
"-fstrict-aliasing",
"-fPIC",
"-fvisibility=hidden",
]
cflags_cc = [
"-std=c++20",
"-fvisibility-inlines-hidden",
]
cflags_objcc = cflags_cc
defines = []
ldflags = []
libs = [ "pthread" ]
# TODO(crbug.com/41481467): Consider creating a bot running partition_alloc
# with extra flags enforced only in the standalone configuration. Then we can
# remove the extra warnings when embedded.
}
config("no_exceptions") {
cflags_cc = [ "-fno-exceptions" ]
cflags_objcc = cflags_cc
}
config("no_rtti") {
cflags_cc = [ "-fno-rtti" ]
cflags_objcc = cflags_cc
}
config("optimize") {
cflags = [ "-O3" ]
}
config("NDEBUG") {
defines = [ "NDEBUG" ]
}
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Copied from Skia's //gn/rm.py
import os
import shutil
import sys
dst, = sys.argv[1:]
if os.path.exists(dst):
if os.path.isdir(dst):
shutil.rmtree(dst)
else:
os.remove(dst)
@@ -0,0 +1,61 @@
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
toolchain("clang") {
ar = "llvm-ar"
cc = "clang"
cxx = "clang++"
link = "clang++"
tool("cc") {
depfile = "{{output}}.d"
command = "$cc -MD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
depsformat = "gcc"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
description = "CC {{source}}"
}
tool("cxx") {
depfile = "{{output}}.d"
command = "$cxx -MD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
depsformat = "gcc"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
description = "CXX {{source}}"
}
tool("alink") {
rspfile = "{{output}}.rsp"
rspfile_content = "{{inputs}}"
rm_py = rebase_path("../rm.py")
command =
"python3 \"$rm_py\" \"{{output}}\" && $ar rcs {{output}} @$rspfile"
outputs = [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ]
default_output_extension = ".a"
output_prefix = "lib"
description = "LINK (static) {{output}}"
}
tool("solink") {
soname = "{{target_output_name}}{{output_extension}}"
rpath = "-Wl,-soname,$soname"
rspfile = "{{output}}.rsp"
rspfile_content = "{{inputs}}"
command = "$link -shared {{ldflags}} @$rspfile {{frameworks}} {{solibs}} {{libs}} $rpath -o {{output}}"
outputs = [ "{{root_out_dir}}/$soname" ]
output_prefix = "lib"
default_output_extension = ".so"
description = "LINK (shared) {{output}}"
}
tool("stamp") {
command = "touch {{output}}"
description = "STAMP {{output}}"
}
}
@@ -2,8 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/cronet/config.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build_overrides/partition_alloc.gni")
# PartitionAlloc have limited support for MSVC's cl.exe compiler. It can only
@@ -79,16 +77,6 @@ if (is_nacl) {
}
declare_args() {
# Turns on compiler optimizations in PartitionAlloc in Debug build.
# If enabling PartitionAlloc-Everywhere in Debug build for tests in Debug
# build, since all memory allocations and deallocations are executed by
# non-optimized PartitionAlloc, chrome (including tests) will be much
# slower. This will cause debug trybots' timeouts. If we want to debug
# PartitionAlloc itself, use partition_alloc_optimized_debug=false.
# Otherwise, use partition_alloc_optimized_debug=true to enable optimized
# PartitionAlloc.
partition_alloc_optimized_debug = true
# PartitionAlloc-Everywhere (PA-E). Causes allocator_shim.cc to route
# calls to PartitionAlloc, rather than some other platform allocator.
use_partition_alloc_as_malloc = use_partition_alloc && use_allocator_shim &&
@@ -221,7 +209,7 @@ declare_args() {
enable_backup_ref_ptr_instance_tracer = false
backup_ref_ptr_extra_oob_checks =
false && enable_backup_ref_ptr_support && use_raw_ptr_backup_ref_impl
enable_backup_ref_ptr_support && use_raw_ptr_backup_ref_impl
}
declare_args() {
@@ -374,14 +362,15 @@ assert(build_with_chromium || !use_asan_backup_ref_ptr,
assert(!use_asan_backup_ref_ptr || use_raw_ptr_hookable_impl,
"AsanBackupRefPtr requires RawPtrHookableImpl")
# pkeys support is explicitly disabled in all Cronet builds, as some test
# dependencies that use partition_allocator are compiled in AOSP against a
# version of glibc that does not include pkeys syscall numbers.
is_pkeys_available =
(is_linux || is_chromeos) && current_cpu == "x64" && !is_cronet_build
declare_args() {
# pkeys support is explicitly disabled in all Cronet builds, as some test
# dependencies that use partition_allocator are compiled in AOSP against a
# version of glibc that does not include pkeys syscall numbers.
enable_pkeys =
(is_linux || is_chromeos) && target_cpu == "x64" && !is_cronet_build
enable_pkeys = is_pkeys_available
}
assert(!enable_pkeys || ((is_linux || is_chromeos) && target_cpu == "x64"),
assert(!enable_pkeys || is_pkeys_available,
"Pkeys are only supported on x64 linux and ChromeOS")
# Some implementations of raw_ptr<>, like BackupRefPtr, require zeroing when
@@ -420,3 +409,17 @@ declare_args() {
# Embedders may opt-out of using C++ 20 build.
assert_cpp20 = assert_cpp20_default
}
declare_args() {
# Enables compilation of the freelist dispatcher, which we'll use to
# carry out runtime evaluation of PartitionAlloc's two freelist
# implementations: the existing encoded-next freelist and the new
# pool offset freelist. When false, the latter is not built.
#
# This is being exposed as a GN arg because of an undiagnosed crashy
# interaction with Mac PGO builders: crbug.com/338094768#comment20
use_freelist_dispatcher = has_64_bit_pointers && false
}
assert(has_64_bit_pointers || !use_freelist_dispatcher,
"freelist dispatcher can't be used without 64-bit pointers")
@@ -2,16 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/config.gni")
import("//build/config/cast.gni")
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/dcheck_always_on.gni")
import("//build/config/logging.gni")
import("../../partition_alloc.gni")
import("buildflag_header.gni")
# //build_overrides/partition_alloc.gni should define partition_alloc_{
# add,remove}_configs. But if not defined (e.g. the embedder misses the config),
# define them here.
if (!defined(partition_alloc_add_configs)) {
partition_alloc_add_configs = []
}
if (!defined(partition_alloc_remove_configs)) {
partition_alloc_remove_configs = []
}
# Add partition_alloc.gni and import it for partition_alloc configs.
# TODO(crbug.com/40276913): Split PartitionAlloc into a public and
@@ -87,19 +90,6 @@ config("wexit_time_destructors") {
}
}
_remove_configs = []
_add_configs = []
if (!is_debug || partition_alloc_optimized_debug) {
_remove_configs += [ "//build/config/compiler:default_optimization" ]
# PartitionAlloc is relatively hot (>1% of cycles for users of CrOS).
# Use speed-focused optimizations for it.
_add_configs += [ "//build/config/compiler:optimize_speed" ]
} else {
_remove_configs += [ "//build/config/compiler:default_optimization" ]
_add_configs += [ "//build/config/compiler:no_optimize" ]
}
source_set("build_config") {
sources = [
"build_config.h",
@@ -151,17 +141,11 @@ component("raw_ptr") {
# See also: `partition_alloc_base/component_export.h`
defines = [ "IS_RAW_PTR_IMPL" ]
configs -= _remove_configs
configs += _add_configs
configs -= partition_alloc_remove_configs
configs += partition_alloc_add_configs
configs += [ ":dependants_extra_warnings" ]
}
# Enables compilation of the freelist dispatcher, which we'll use to
# carry out runtime evaluation of PartitionAlloc's two freelist
# implementations: the existing encoded-next freelist and the new
# pool offset freelist. When false, the latter is not built.
use_freelist_dispatcher = has_64_bit_pointers && false
pa_buildflag_header("partition_alloc_buildflags") {
header = "partition_alloc_buildflags.h"
@@ -232,6 +216,7 @@ pa_buildflag_header("partition_alloc_buildflags") {
"FORWARD_THROUGH_MALLOC=$forward_through_malloc",
"ASSERT_CPP_20=$assert_cpp20",
"IS_DEBUG=$is_debug",
]
}
@@ -258,10 +243,7 @@ pa_buildflag_header("chromecast_buildflags") {
pa_buildflag_header("chromeos_buildflags") {
header = "chromeos_buildflags.h"
# TODO(https://crbug.com/41481467): Remove the "PA_" prefix, because it
# will already be part of the define and the `PA_BUILDFLAG` macro.
flags = [ "PA_IS_CHROMEOS_ASH=$is_chromeos_ash" ]
flags = [ "IS_CHROMEOS=$is_chromeos" ]
}
pa_buildflag_header("debugging_buildflags") {
@@ -598,8 +580,8 @@ if (is_clang_or_gcc) {
]
}
configs -= _remove_configs
configs += _add_configs
configs -= partition_alloc_remove_configs
configs += partition_alloc_add_configs
configs += [ ":dependants_extra_warnings" ]
# We want to be able to test pkey mode without access to the default pkey.
@@ -709,9 +691,6 @@ if (is_clang_or_gcc) {
sources += [ "partition_alloc_base/debug/stack_trace_linux.cc" ]
}
if (is_android || is_chromeos_ash) {
sources += [ "partition_alloc_base/time/time_android.cc" ]
}
if (is_apple) {
# Request <dlfcn.h> to provide the `dladdr()` function. This is used to
# translate address to symbolic information.
@@ -802,8 +781,8 @@ if (is_clang_or_gcc) {
]
}
configs -= _remove_configs
configs += _add_configs
configs -= partition_alloc_remove_configs
configs += partition_alloc_add_configs
configs += [ ":dependants_extra_warnings" ]
}
@@ -820,8 +799,8 @@ if (is_clang_or_gcc) {
]
frameworks = []
configs -= _remove_configs
configs += _add_configs
configs -= partition_alloc_remove_configs
configs += partition_alloc_add_configs
configs += [ ":dependants_extra_warnings" ]
shim_headers = []
@@ -881,7 +860,7 @@ if (is_clang_or_gcc) {
# Do not compile with ARC because this target has to interface with
# low-level Objective-C and having ARC would interfere.
configs -= [ "//build/config/compiler:enable_arc" ]
configs -= [ partition_alloc_enable_arc_config ]
}
}
if (is_chromeos || is_linux) {
@@ -10,11 +10,13 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_buildflags.h"
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) && !defined(__MUSL__)
#if defined(__MUSL__)
// Musl does not support ifunc.
#elif PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_LINUX)
#define HAS_HW_CAPS
#endif
#if defined(ARCH_CPU_ARM64) && defined(HAS_HW_CAPS)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64) && defined(HAS_HW_CAPS)
#include <asm/hwcap.h>
#include <sys/ifunc.h>
#else
@@ -25,7 +27,7 @@ namespace partition_alloc::internal {
constexpr bool IsBtiEnabled(uint64_t ifunc_hwcap,
struct __ifunc_arg_t* ifunc_hw) {
#if defined(ARCH_CPU_ARM64) && defined(HAS_HW_CAPS)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64) && defined(HAS_HW_CAPS)
return (ifunc_hwcap & _IFUNC_ARG_HWCAP) && (ifunc_hw->_hwcap2 & HWCAP2_BTI);
#else
return false;
@@ -34,7 +36,7 @@ constexpr bool IsBtiEnabled(uint64_t ifunc_hwcap,
constexpr bool IsMteEnabled(uint64_t ifunc_hwcap,
struct __ifunc_arg_t* ifunc_hw) {
#if defined(ARCH_CPU_ARM64) && defined(HAS_HW_CAPS) && \
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64) && defined(HAS_HW_CAPS) && \
PA_BUILDFLAG(HAS_MEMORY_TAGGING)
return (ifunc_hwcap & _IFUNC_ARG_HWCAP) && (ifunc_hw->_hwcap2 & HWCAP2_MTE);
#else
@@ -21,7 +21,7 @@
#include "partition_alloc/reservation_offset_table.h"
#include "partition_alloc/thread_isolation/alignment.h"
#if BUILDFLAG(IS_APPLE) || PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
#if PA_BUILDFLAG(IS_APPLE) || PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
#include <sys/mman.h>
#endif
@@ -9,7 +9,7 @@
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/random.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
@@ -27,7 +27,7 @@ uintptr_t GetRandomPageBase() {
random &= internal::ASLRMask();
random += internal::ASLROffset();
#else // PA_BUILDFLAG(HAS_64_BIT_POINTERS)
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// On win32 host systems the randomization plus huge alignment causes
// excessive fragmentation. Plus most of these systems lack ASLR, so the
// randomization isn't buying anything. In that case we just skip it.
@@ -39,7 +39,7 @@ uintptr_t GetRandomPageBase() {
if (!is_wow64) {
return 0;
}
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
random &= internal::ASLRMask();
random += internal::ASLROffset();
#endif // PA_BUILDFLAG(HAS_64_BIT_POINTERS)
@@ -36,7 +36,7 @@ AslrMask(uintptr_t bits) {
//
// clang-format off
#if defined(ARCH_CPU_64_BITS)
#if PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
@@ -54,7 +54,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0x7e8000000000ULL);
}
#elif BUILDFLAG(IS_WIN)
#elif PA_BUILDFLAG(IS_WIN)
// Windows 8.10 and newer support the full 48 bit address range. Since
// ASLROffset() is non-zero and may cause a carry, use 47 bit masks. See
@@ -67,7 +67,7 @@ AslrMask(uintptr_t bits) {
return 0x80000000ULL;
}
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
// macOS as of 10.12.5 does not clean up entries in page map levels 3/4
// [PDP/PML4] created from mmap or mach_vm_allocate, even after the region
@@ -98,9 +98,9 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0x10000000000ULL);
}
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#if defined(ARCH_CPU_X86_64)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_64)
// Linux (and macOS) support the full 47-bit user space of x64 processors.
// Use only 46 to allow the kernel a chance to fulfill the request.
@@ -113,7 +113,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0);
}
#elif BUILDFLAG(IS_ANDROID) && (defined(ARCH_CPU_ARM64) || defined(ARCH_CPU_RISCV64))
#elif PA_BUILDFLAG(IS_ANDROID) && (PA_BUILDFLAG(PA_ARCH_CPU_ARM64) || PA_BUILDFLAG(PA_ARCH_CPU_RISCV64))
// Restrict the address range on Android to avoid a large performance
// regression in single-process WebViews. See https://crbug.com/837640.
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR uintptr_t
@@ -124,8 +124,8 @@ AslrMask(uintptr_t bits) {
ASLROffset() {
return AslrAddress(0x20000000ULL);
}
#elif defined(ARCH_CPU_ARM64)
#if BUILDFLAG(IS_LINUX)
#elif PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
#if PA_BUILDFLAG(IS_LINUX)
// Linux on arm64 can use 39, 42, 48, or 52-bit user space, depending on
// page size and number of levels of translation pages used. We use
@@ -153,9 +153,9 @@ AslrMask(uintptr_t bits) {
#endif
#elif defined(ARCH_CPU_PPC64)
#elif PA_BUILDFLAG(PA_ARCH_CPU_PPC64)
#if BUILDFLAG(IS_AIX)
#if PA_BUILDFLAG(IS_AIX)
// AIX has 64 bits of virtual addressing, but we limit the address range
// to (a) minimize segment lookaside buffer (SLB) misses; and (b) use
@@ -167,7 +167,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0x400000000000ULL);
}
#elif defined(ARCH_CPU_BIG_ENDIAN)
#elif PA_BUILDFLAG(PA_ARCH_CPU_BIG_ENDIAN)
// Big-endian Linux PPC has 44 bits of virtual addressing. Use 42.
PA_ALWAYS_INLINE constexpr uintptr_t ASLRMask() {
@@ -177,7 +177,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0);
}
#else // !BUILDFLAG(IS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
#else // !PA_BUILDFLAG(IS_AIX) && !PA_BUILDFLAG(PA_ARCH_CPU_BIG_ENDIAN)
// Little-endian Linux PPC has 48 bits of virtual addressing. Use 46.
PA_ALWAYS_INLINE constexpr uintptr_t ASLRMask() {
@@ -187,9 +187,9 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0);
}
#endif // !BUILDFLAG(IS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
#endif // !PA_BUILDFLAG(IS_AIX) && !PA_BUILDFLAG(PA_ARCH_CPU_BIG_ENDIAN)
#elif defined(ARCH_CPU_S390X)
#elif PA_BUILDFLAG(PA_ARCH_CPU_S390X)
// Linux on Z uses bits 22 - 32 for Region Indexing, which translates to
// 42 bits of virtual addressing. Truncate to 40 bits to allow kernel a
@@ -201,7 +201,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0);
}
#elif defined(ARCH_CPU_S390)
#elif PA_BUILDFLAG(PA_ARCH_CPU_S390)
// 31 bits of virtual addressing. Truncate to 29 bits to allow the kernel
// a chance to fulfill the request.
@@ -212,8 +212,8 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0);
}
#else // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) &&
// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
#else // !PA_BUILDFLAG(PA_ARCH_CPU_X86_64) && !PA_BUILDFLAG(PA_ARCH_CPU_PPC64) &&
// !PA_BUILDFLAG(PA_ARCH_CPU_S390X) && !PA_BUILDFLAG(PA_ARCH_CPU_S390)
// For all other POSIX variants, use 30 bits.
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR uintptr_t
@@ -221,7 +221,7 @@ AslrMask(uintptr_t bits) {
return AslrMask(30);
}
#if BUILDFLAG(IS_SOLARIS)
#if PA_BUILDFLAG(IS_SOLARIS)
// For our Solaris/illumos mmap hint, we pick a random address in the
// bottom half of the top half of the address space (that is, the third
@@ -237,7 +237,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0x80000000ULL);
}
#elif BUILDFLAG(IS_AIX)
#elif PA_BUILDFLAG(IS_AIX)
// The range 0x30000000 - 0xD0000000 is available on AIX; choose the
// upper range.
@@ -245,7 +245,7 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0x90000000ULL);
}
#else // !BUILDFLAG(IS_SOLARIS) && !BUILDFLAG(IS_AIX)
#else // !PA_BUILDFLAG(IS_SOLARIS) && !PA_BUILDFLAG(IS_AIX)
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macOS
@@ -255,14 +255,14 @@ AslrMask(uintptr_t bits) {
return AslrAddress(0x20000000ULL);
}
#endif // !BUILDFLAG(IS_SOLARIS) && !BUILDFLAG(IS_AIX)
#endif // !PA_BUILDFLAG(IS_SOLARIS) && !PA_BUILDFLAG(IS_AIX)
#endif // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) &&
// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
#endif // !PA_BUILDFLAG(PA_ARCH_CPU_X86_64) && !PA_BUILDFLAG(PA_ARCH_CPU_PPC64) &&
// !PA_BUILDFLAG(PA_ARCH_CPU_S390X) && !PA_BUILDFLAG(PA_ARCH_CPU_S390)
#endif // BUILDFLAG(IS_POSIX)
#endif // PA_BUILDFLAG(IS_POSIX)
#elif defined(ARCH_CPU_32_BITS)
#elif PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
// This is a good range on 32-bit Windows and Android (the only platforms on
// which we support 32-bitness). Allocates in the 0.5 - 1.5 GiB region. There
@@ -278,9 +278,9 @@ AslrMask(uintptr_t bits) {
#error Please tell us about your exotic hardware! Sounds interesting.
#endif // defined(ARCH_CPU_32_BITS)
#endif // PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
// clang-format on
// clang-format on
} // namespace internal
@@ -7,7 +7,7 @@
#include "partition_alloc/build_config.h"
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
extern "C" {
/**
* A valid BTI function. Jumping to this funtion should not cause any problem in
@@ -26,6 +26,6 @@ int64_t arm_bti_test_function_invalid_offset(int64_t);
**/
void arm_bti_test_function_end(void);
}
#endif // defined(ARCH_CPU_ARM64)
#endif // PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
#endif // PARTITION_ALLOC_ARM_BTI_TEST_FUNCTIONS_H_
@@ -4,7 +4,507 @@
#ifndef PARTITION_ALLOC_BUILD_CONFIG_H_
#define PARTITION_ALLOC_BUILD_CONFIG_H_
// TODO(https://crbug.com/41481467): Remove //build dependency.
#include "build/build_config.h"
// This file is derived from chromium's //build/build_config.h.
//
// Differences:
// - Only the definition used by partition_alloc are included.
// - The definition can only be consumed PA_BUILDFLAG(...) macro. This avoids
// silent failure when developers forget to include this file. This avoids the
// need of a PRESUBMIT.py to enforce the inclusion of this file.
//
//
// This files contains the following definition:
//
// Operating system:
// IS_IOS / IS_AIX / IS_ANDROID / IS_ASMJS / IS_FREEBSD / IS_FUCHSIA /
// IS_LINUX / IS_MAC / IS_NACL / IS_NETBSD / IS_OPENBSD / IS_QNX /
// IS_SOLARIS / IS_WIN
//
// Operating system family:
// IS_APPLE / IS_BSD / IS_POSIX
//
// Compiler:
// PA_COMPILER_GCC / PA_COMPILER_MSVC
//
// Processor:
// PA_ARCH_CPU_ARM64 / PA_ARCH_CPU_ARMEL / PA_ARCH_CPU_BIG_ENDIAN /
// PA_ARCH_CPU_LITTLE_ENDIAN / PA_ARCH_CPU_MIPS / PA_ARCH_CPU_MIPS64 /
// PA_ARCH_CPU_MIPS64EL / PA_ARCH_CPU_MIPSEL / PA_ARCH_CPU_PPC64 /
// PA_ARCH_CPU_RISCV64 / PA_ARCH_CPU_S390 / PA_ARCH_CPU_S390X /
// PA_ARCH_CPU_X86 / PA_ARCH_CPU_X86_64
//
// Processor Family:
// PA_ARCH_CPU_32_BITS / PA_ARCH_CPU_64_BITS / PA_ARCH_CPU_ARM_FAMILY /
// PA_ARCH_CPU_LOONGPA_ARCH64 / PA_ARCH_CPU_PPC64_FAMILY /
// PA_ARCH_CPU_S390_FAMILY / PA_ARCH_CPU_X86_FAMILY
//
// Compiler:
// PA_COMPILER_GCC / PA_COMPILER_MSVC
//
// Standard library:
// PA_LIBC_GLIBC
// Definition of PA_BUILDFLAG(...) macro.
#include "partition_alloc/buildflag.h" // IWYU pragma: export
// Definition of PA_BUILDFLAG(IS_CHROMEOS).
#include "partition_alloc/chromeos_buildflags.h" // IWYU pragma: export
// Clangd does not detect PA_BUILDFLAG_INTERNAL_* indirect usage, so mark the
// header as "always_keep" to avoid "unused include" warning.
//
// IWYU pragma: always_keep
// A set of macros to use for platform detection.
#if defined(__native_client__)
// __native_client__ must be first, so that other IS_ defines are not set.
#define PA_IS_NACL
#elif defined(ANDROID)
#define PA_IS_ANDROID
#elif defined(__APPLE__)
// Only include TargetConditionals after testing ANDROID as some Android builds
// on the Mac have this header available and it's not needed unless the target
// is really an Apple platform.
#include <TargetConditionals.h>
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#define PA_IS_IOS
#else
#define PA_IS_MAC
#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#elif defined(__linux__)
#if !PA_BUILDFLAG(IS_CHROMEOS)
// Do not define PA_IS_LINUX on Chrome OS build.
// The IS_CHROMEOS PA_BUILDFLAG macro is defined in chromeos_buildflags.h.
#define PA_IS_LINUX
#endif // !PA_BUILDFLAG(IS_CHROMEOS)
// Include a system header to pull in features.h for glibc/uclibc macros.
#include <assert.h>
#if defined(__GLIBC__) && !defined(__UCLIBC__)
// We really are using glibc, not uClibc pretending to be glibc.
#define PA_LIBC_GLIBC
#endif
#elif defined(_WIN32)
#define PA_IS_WIN
#elif defined(__Fuchsia__)
#define PA_IS_FUCHSIA
#elif defined(__FreeBSD__)
#define PA_IS_FREEBSD
#elif defined(__NetBSD__)
#define PA_IS_NETBSD
#elif defined(__OpenBSD__)
#define PA_IS_OPENBSD
#elif defined(__sun)
#define PA_IS_SOLARIS
#elif defined(__QNXNTO__)
#define PA_IS_QNX
#elif defined(_AIX)
#define PA_IS_AIX
#elif defined(__asmjs__) || defined(__wasm__)
#define PA_IS_ASMJS
#endif
// NOTE: Adding a new port? Please follow
// https://chromium.googlesource.com/chromium/src/+/main/docs/new_port_policy.md
#if defined(PA_IS_MAC) || defined(PA_IS_IOS)
#define PA_IS_APPLE
#endif
#if defined(PA_IS_FREEBSD) || defined(PA_IS_NETBSD) || defined(PA_IS_OPENBSD)
#define PA_IS_BSD
#endif
#if defined(PA_IS_AIX) || defined(PA_IS_ANDROID) || defined(PA_IS_ASMJS) || \
defined(PA_IS_FREEBSD) || defined(PA_IS_IOS) || defined(PA_IS_LINUX) || \
defined(PA_IS_CHROMEOS) || defined(PA_IS_MAC) || defined(PA_IS_NACL) || \
defined(PA_IS_NETBSD) || defined(PA_IS_OPENBSD) || defined(PA_IS_QNX) || \
defined(PA_IS_SOLARIS) || PA_BUILDFLAG(IS_CHROMEOS)
#define PA_IS_POSIX
#endif
// Compiler detection. Note: clang masquerades as GCC on POSIX and as MSVC on
// Windows.
#if defined(__GNUC__)
#define PA_COMPILER_GCC
#elif defined(_MSC_VER)
#define PA_COMPILER_MSVC
#endif
// ------
// Processor architecture detection. For more info on what's defined, see:
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
// http://www.agner.org/optimize/calling_conventions.pdf
// or with gcc, run: "echo | gcc -E -dM -"
#if defined(_M_X64) || defined(__x86_64__)
#define PA_ARCH_CPU_X86_FAMILY
#define PA_ARCH_CPU_X86_64
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#elif defined(_M_IX86) || defined(__i386__)
#define PA_ARCH_CPU_X86_FAMILY
#define PA_ARCH_CPU_X86
#define PA_ARCH_CPU_32_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__s390x__)
#define PA_ARCH_CPU_S390_FAMILY
#define PA_ARCH_CPU_S390X
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_BIG_ENDIAN
#elif defined(__s390__)
#define PA_ARCH_CPU_S390_FAMILY
#define PA_ARCH_CPU_S390
#define PA_ARCH_CPU_BIG_ENDIAN
#elif (defined(__PPC64__) || defined(__PPC__)) && defined(__BIG_ENDIAN__)
#define PA_ARCH_CPU_PPC64_FAMILY
#define PA_ARCH_CPU_PPC64
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_BIG_ENDIAN
#elif defined(__PPC64__)
#define PA_ARCH_CPU_PPC64_FAMILY
#define PA_ARCH_CPU_PPC64
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__ARMEL__)
#define PA_ARCH_CPU_ARM_FAMILY
#define PA_ARCH_CPU_ARMEL
#define PA_ARCH_CPU_32_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__aarch64__) || defined(_M_ARM64)
#define PA_ARCH_CPU_ARM_FAMILY
#define PA_ARCH_CPU_ARM64
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__pnacl__) || defined(__asmjs__) || defined(__wasm__)
#define PA_ARCH_CPU_32_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__MIPSEL__)
#if defined(__LP64__)
#define PA_ARCH_CPU_MIPS64EL
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#else
#define PA_ARCH_CPU_MIPSEL
#define PA_ARCH_CPU_32_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#endif
#elif defined(__MIPSEB__)
#if defined(__LP64__)
#define PA_ARCH_CPU_MIPS64
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_BIG_ENDIAN
#else
#define PA_ARCH_CPU_MIPS
#define PA_ARCH_CPU_32_BITS
#define PA_ARCH_CPU_BIG_ENDIAN
#endif
#elif defined(__loongarch__)
#define PA_ARCH_CPU_LITTLE_ENDIAN
#if __loongarch_grlen == 64
#define PA_ARCH_CPU_LOONGARCH64
#define PA_ARCH_CPU_64_BITS
#else
#define PA_ARCH_CPU_32_BITS
#endif
#elif defined(__riscv) && (__riscv_xlen == 64)
#define PA_ARCH_CPU_RISCV64
#define PA_ARCH_CPU_64_BITS
#define PA_ARCH_CPU_LITTLE_ENDIAN
#endif
// The part below can be generated with the following script:
// https://paste.googleplex.com/6324671838683136
//
// It transform the defines above into PA_BUILDFLAG_INTERNAL_* defines, then
// undef the original define.
//
// Usage of PA_BUILDFLAG(...) macro is better than raw define, because it avoids
// silent failure when developers forget to include this file.
#if defined(PA_ARCH_CPU_32_BITS)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_32_BITS() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_32_BITS() (0)
#endif
#undef PA_ARCH_CPU_32_BITS
#if defined(PA_ARCH_CPU_64_BITS)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_64_BITS() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_64_BITS() (0)
#endif
#undef PA_ARCH_CPU_64_BITS
#if defined(PA_ARCH_CPU_ARM64)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_ARM64() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_ARM64() (0)
#endif
#undef PA_ARCH_CPU_ARM64
#if defined(PA_ARCH_CPU_ARMEL)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_ARMEL() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_ARMEL() (0)
#endif
#undef PA_ARCH_CPU_ARMEL
#if defined(PA_ARCH_CPU_ARM_FAMILY)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_ARM_FAMILY() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_ARM_FAMILY() (0)
#endif
#undef PA_ARCH_CPU_ARM_FAMILY
#if defined(PA_ARCH_CPU_BIG_ENDIAN)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_BIG_ENDIAN() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_BIG_ENDIAN() (0)
#endif
#undef PA_ARCH_CPU_BIG_ENDIAN
#if defined(PA_ARCH_CPU_LITTLE_ENDIAN)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_LITTLE_ENDIAN() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_LITTLE_ENDIAN() (0)
#endif
#undef PA_ARCH_CPU_LITTLE_ENDIAN
#if defined(PA_ARCH_CPU_LOONGARCH64)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_LOONGARCH64() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_LOONGARCH64() (0)
#endif
#undef PA_ARCH_CPU_LOONGARCH64
#if defined(PA_ARCH_CPU_MIPS)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPS() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPS() (0)
#endif
#undef PA_ARCH_CPU_MIPS
#if defined(PA_ARCH_CPU_MIPS64)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPS64() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPS64() (0)
#endif
#undef PA_ARCH_CPU_MIPS64
#if defined(PA_ARCH_CPU_MIPS64EL)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPS64EL() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPS64EL() (0)
#endif
#undef PA_ARCH_CPU_MIPS64EL
#if defined(PA_ARCH_CPU_MIPSEL)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPSEL() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_MIPSEL() (0)
#endif
#undef PA_ARCH_CPU_MIPSEL
#if defined(PA_ARCH_CPU_PPC64)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_PPC64() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_PPC64() (0)
#endif
#undef PA_ARCH_CPU_PPC64
#if defined(PA_ARCH_CPU_PPC64_FAMILY)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_PPC64_FAMILY() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_PPC64_FAMILY() (0)
#endif
#undef PA_ARCH_CPU_PPC64_FAMILY
#if defined(PA_ARCH_CPU_RISCV64)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_RISCV64() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_RISCV64() (0)
#endif
#undef PA_ARCH_CPU_RISCV64
#if defined(PA_ARCH_CPU_S390)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_S390() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_S390() (0)
#endif
#undef PA_ARCH_CPU_S390
#if defined(PA_ARCH_CPU_S390_FAMILY)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_S390_FAMILY() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_S390_FAMILY() (0)
#endif
#undef PA_ARCH_CPU_S390_FAMILY
#if defined(PA_ARCH_CPU_S390X)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_S390X() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_S390X() (0)
#endif
#undef PA_ARCH_CPU_S390X
#if defined(PA_ARCH_CPU_X86)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_X86() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_X86() (0)
#endif
#undef PA_ARCH_CPU_X86
#if defined(PA_ARCH_CPU_X86_64)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_X86_64() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_X86_64() (0)
#endif
#undef PA_ARCH_CPU_X86_64
#if defined(PA_ARCH_CPU_X86_FAMILY)
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_X86_FAMILY() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_ARCH_CPU_X86_FAMILY() (0)
#endif
#undef PA_ARCH_CPU_X86_FAMILY
#if defined(PA_COMPILER_GCC)
#define PA_BUILDFLAG_INTERNAL_PA_COMPILER_GCC() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_COMPILER_GCC() (0)
#endif
#undef PA_COMPILER_GCC
#if defined(PA_COMPILER_MSVC)
#define PA_BUILDFLAG_INTERNAL_PA_COMPILER_MSVC() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_COMPILER_MSVC() (0)
#endif
#undef PA_COMPILER_MSVC
#if defined(PA_IS_AIX)
#define PA_BUILDFLAG_INTERNAL_IS_AIX() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_AIX() (0)
#endif
#undef PA_IS_AIX
#if defined(PA_IS_ANDROID)
#define PA_BUILDFLAG_INTERNAL_IS_ANDROID() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_ANDROID() (0)
#endif
#undef PA_IS_ANDROID
#if defined(PA_IS_APPLE)
#define PA_BUILDFLAG_INTERNAL_IS_APPLE() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_APPLE() (0)
#endif
#undef PA_IS_APPLE
#if defined(PA_IS_ASMJS)
#define PA_BUILDFLAG_INTERNAL_IS_ASMJS() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_ASMJS() (0)
#endif
#undef PA_IS_ASMJS
#if defined(PA_IS_BSD)
#define PA_BUILDFLAG_INTERNAL_IS_BSD() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_BSD() (0)
#endif
#undef PA_IS_BSD
#if defined(PA_IS_FREEBSD)
#define PA_BUILDFLAG_INTERNAL_IS_FREEBSD() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_FREEBSD() (0)
#endif
#undef PA_IS_FREEBSD
#if defined(PA_IS_FUCHSIA)
#define PA_BUILDFLAG_INTERNAL_IS_FUCHSIA() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_FUCHSIA() (0)
#endif
#undef PA_IS_FUCHSIA
#if defined(PA_IS_IOS)
#define PA_BUILDFLAG_INTERNAL_IS_IOS() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_IOS() (0)
#endif
#undef PA_IS_IOS
#if defined(PA_IS_LINUX)
#define PA_BUILDFLAG_INTERNAL_IS_LINUX() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_LINUX() (0)
#endif
#undef PA_IS_LINUX
#if defined(PA_IS_MAC)
#define PA_BUILDFLAG_INTERNAL_IS_MAC() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_MAC() (0)
#endif
#undef PA_IS_MAC
#if defined(PA_IS_NACL)
#define PA_BUILDFLAG_INTERNAL_IS_NACL() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_NACL() (0)
#endif
#undef PA_IS_NACL
#if defined(PA_IS_NETBSD)
#define PA_BUILDFLAG_INTERNAL_IS_NETBSD() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_NETBSD() (0)
#endif
#undef PA_IS_NETBSD
#if defined(PA_IS_OPENBSD)
#define PA_BUILDFLAG_INTERNAL_IS_OPENBSD() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_OPENBSD() (0)
#endif
#undef PA_IS_OPENBSD
#if defined(PA_IS_POSIX)
#define PA_BUILDFLAG_INTERNAL_IS_POSIX() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_POSIX() (0)
#endif
#undef PA_IS_POSIX
#if defined(PA_IS_QNX)
#define PA_BUILDFLAG_INTERNAL_IS_QNX() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_QNX() (0)
#endif
#undef PA_IS_QNX
#if defined(PA_IS_SOLARIS)
#define PA_BUILDFLAG_INTERNAL_IS_SOLARIS() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_SOLARIS() (0)
#endif
#undef PA_IS_SOLARIS
#if defined(PA_IS_WIN)
#define PA_BUILDFLAG_INTERNAL_IS_WIN() (1)
#else
#define PA_BUILDFLAG_INTERNAL_IS_WIN() (0)
#endif
#undef PA_IS_WIN
#if defined(PA_LIBC_GLIBC)
#define PA_BUILDFLAG_INTERNAL_PA_LIBC_GLIBC() (1)
#else
#define PA_BUILDFLAG_INTERNAL_PA_LIBC_GLIBC() (0)
#endif
#undef PA_LIBC_GLIBC
#endif // PARTITION_ALLOC_BUILD_CONFIG_H_
@@ -0,0 +1,17 @@
digraph {
layout = "circo"
dpi = 156
node[shape=box]
crt[shape=circle, label="(not yet fully\ninitialized)\nWindows\nCRT"]
malloc[label="malloc()"]
crt->malloc[label="calls"]
malloc->PartitionAlloc[label="intercepted\nby"]
static_local[label="nontrivial\nfunction-local\nstatic"]
PartitionAlloc->static_local[label="initializes"]
lock[label="critical section\n(implicit lock)"]
static_local->lock[label="enters"]
lock->crt[label="attempts\nre-entry\ninto", style=dotted]
}
@@ -17,7 +17,7 @@
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/partition_alloc_constants.h"
#if !defined(ARCH_CPU_BIG_ENDIAN)
#if !PA_BUILDFLAG(PA_ARCH_CPU_BIG_ENDIAN)
#include "partition_alloc/reverse_bytes.h"
#endif
@@ -57,7 +57,7 @@ class EncodedFreelistPtr {
// corrupt a freelist pointer, partial pointer overwrite attacks are
// thwarted.
// For big endian, similar guarantees are arrived at with a negation.
#if defined(ARCH_CPU_BIG_ENDIAN)
#if PA_BUILDFLAG(PA_ARCH_CPU_BIG_ENDIAN)
uintptr_t transformed = ~address;
#else
uintptr_t transformed = ReverseBytes(address);
@@ -64,14 +64,14 @@ void* GwpAsanSupport::MapRegion(size_t slot_count,
return nullptr;
}
#if defined(ARCH_CPU_64_BITS)
#if PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
// Mapping the GWP-ASan region in to the lower 32-bits of address space
// makes it much more likely that a bad pointer dereference points into
// our region and triggers a false positive report. We rely on the fact
// that PA address pools are never allocated in the first 4GB due to
// their alignment requirements.
PA_CHECK(super_page_span_start >= (1ULL << 32));
#endif // defined(ARCH_CPU_64_BITS)
#endif // PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
uintptr_t super_page_span_end =
super_page_span_start + super_page_count * kSuperPageSize;
@@ -24,9 +24,9 @@
#include "partition_alloc/partition_alloc_forward.h"
#include "partition_alloc/tagging.h"
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
#include "partition_alloc/partition_alloc_base/bits.h"
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
namespace partition_alloc::internal {
@@ -42,11 +42,11 @@ namespace partition_alloc::internal {
// this gating.
PA_ALWAYS_INLINE size_t
AlignUpInSlotMetadataSizeForApple(size_t in_slot_metadata_size) {
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
return internal::base::bits::AlignUp<size_t>(in_slot_metadata_size, 8);
#else
return in_slot_metadata_size;
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
}
#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
@@ -261,11 +261,14 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) InSlotMetadata {
PA_ALWAYS_INLINE bool ReleaseFromAllocator() {
CheckCookieIfSupported();
// TODO(bartekn): Make the double-free check more effective. Once freed, the
// in-slot metadata is overwritten by an encoded freelist-next pointer.
CountType old_count =
count_.fetch_and(~kMemoryHeldByAllocatorBit, std::memory_order_release);
// If kMemoryHeldByAllocatorBit was already unset, it indicates a double
// free, but it could also be caused by a memory corruption. Note, this
// detection mechanism isn't perfect, because in-slot-metadata can be
// overwritten by the freelist pointer (or its shadow) for very small slots,
// thus masking the error away.
if (PA_UNLIKELY(!(old_count & kMemoryHeldByAllocatorBit))) {
DoubleFreeOrCorruptionDetected(old_count);
}
@@ -105,7 +105,8 @@ bool LightweightQuarantineBranch::Quarantine(void* object,
bool LightweightQuarantineBranch::IsQuarantinedForTesting(void* object) {
ConditionalScopedGuard guard(lock_required_, lock_);
uintptr_t slot_start = root_.allocator_root_.ObjectToSlotStart(object);
uintptr_t slot_start =
root_.allocator_root_.ObjectToSlotStartUnchecked(object);
for (const auto& slot : slots_) {
if (slot.slot_start == slot_start) {
return true;
@@ -52,6 +52,13 @@ void MemoryReclaimer::ReclaimNormal() {
Reclaim(kFlags);
}
void MemoryReclaimer::ReclaimFast() {
constexpr int kFlags = PurgeFlags::kDecommitEmptySlotSpans |
PurgeFlags::kDiscardUnusedSystemPages |
PurgeFlags::kLimitDuration;
Reclaim(kFlags);
}
void MemoryReclaimer::Reclaim(int flags) {
internal::ScopedGuard lock(
lock_); // Has to protect from concurrent (Un)Register calls.
@@ -51,6 +51,8 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) MemoryReclaimer {
// Triggers an explicit reclaim now reclaiming all free memory
void ReclaimAll();
// Same as ReclaimNormal(), but return early if reclaim takes too long.
void ReclaimFast();
private:
MemoryReclaimer();
@@ -10,12 +10,12 @@
#include "partition_alloc/partition_alloc_base/debug/alias.h"
#include "partition_alloc/partition_alloc_base/immediate_crash.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#include <array>
#include <cstdlib>
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
namespace partition_alloc {
@@ -28,7 +28,7 @@ namespace internal {
// partition_alloc::internal::base::internal::OnNoMemoryInternal
PA_NOINLINE void OnNoMemoryInternal(size_t size) {
g_oom_size = size;
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// Kill the process. This is important for security since most of code
// does not check the result of memory allocation.
// https://msdn.microsoft.com/en-us/library/het71c37.aspx
@@ -55,7 +55,7 @@ PA_NOINLINE void OnNoMemoryInternal(size_t size) {
// to be able to successfully unwind through libc to get to the correct
// address, which is particularly an issue on Android.
PA_IMMEDIATE_CRASH();
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
}
} // namespace internal
@@ -12,7 +12,7 @@
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include "partition_alloc/partition_alloc_base/win/windows_types.h"
#endif
@@ -30,7 +30,7 @@ void TerminateBecauseOutOfMemory(size_t size);
// TODO: this can be removed when Breakpad is no longer supported.
PA_COMPONENT_EXPORT(PARTITION_ALLOC) extern size_t g_oom_size;
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
namespace win {
// Custom Windows exception code chosen to indicate an out of memory error.
@@ -15,15 +15,15 @@
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_lock.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include "partition_alloc/page_allocator_internals_win.h"
#elif BUILDFLAG(IS_POSIX)
#elif PA_BUILDFLAG(IS_POSIX)
#include "partition_alloc/page_allocator_internals_posix.h"
#elif BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_FUCHSIA)
#include "partition_alloc/page_allocator_internals_fuchsia.h"
#else
#error Platform not supported.
@@ -197,7 +197,7 @@ uintptr_t AllocPagesWithAlignOffset(
}
// First try to force an exact-size, aligned allocation from our random base.
#if defined(ARCH_CPU_32_BITS)
#if PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
// On 32 bit systems, first try one random aligned address, and then try an
// aligned address derived from the value of |ret|.
constexpr int kExactSizeTries = 2;
@@ -224,13 +224,13 @@ uintptr_t AllocPagesWithAlignOffset(
}
}
#if defined(ARCH_CPU_32_BITS)
#if PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
// For small address spaces, try the first aligned address >= |ret|. Note
// |ret| may be null, in which case |address| becomes null. If
// |align_offset| is non-zero, this calculation may get us not the first,
// but the next matching address.
address = ((ret + align_offset_mask) & align_base_mask) + align_offset;
#else // defined(ARCH_CPU_64_BITS)
#else // PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
// Keep trying random addresses on systems that have a large address space.
address = NextAlignedWithOffset(GetRandomPageBase(), align, align_offset);
#endif
@@ -409,7 +409,7 @@ size_t GetTotalMappedSize() {
return g_total_mapped_address_space;
}
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
namespace {
bool g_retry_on_commit_failure = false;
}
@@ -259,7 +259,7 @@ bool DecommitAndZeroSystemPages(void* address,
// recommitted. Do not assume that this will not change over time.
constexpr PA_COMPONENT_EXPORT(
PARTITION_ALLOC) bool DecommittedMemoryIsAlwaysZeroed() {
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
return false;
#elif defined(NO_MADVISE_SYSCALL)
return false;
@@ -382,14 +382,14 @@ PA_COMPONENT_EXPORT(PARTITION_ALLOC) uint32_t GetAllocPageErrorCode();
// to assess address space pressure.
PA_COMPONENT_EXPORT(PARTITION_ALLOC) size_t GetTotalMappedSize();
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// Sets whether to retry the allocation of pages when a commit failure
// happens. This doesn't cover cases where the system is out of address space,
// or reaches another limit.
PA_COMPONENT_EXPORT(PARTITION_ALLOC)
void SetRetryOnCommitFailure(bool retry_on_commit_failure);
bool GetRetryOnCommitFailure();
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
} // namespace partition_alloc
@@ -11,7 +11,7 @@
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS)
#if PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
#include <mach/vm_page_size.h>
@@ -25,8 +25,8 @@
// elimination.
#define PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR __attribute__((const))
#elif (BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_64_BITS)) || \
(BUILDFLAG(IS_LINUX) && defined(ARCH_CPU_ARM64))
#elif (PA_BUILDFLAG(IS_ANDROID) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)) || \
(PA_BUILDFLAG(IS_LINUX) && PA_BUILDFLAG(PA_ARCH_CPU_ARM64))
// This should work for all POSIX (if needed), but currently all other
// supported OS/architecture combinations use either hard-coded values
// (such as x86) or have means to determine these values without needing
@@ -68,14 +68,14 @@ extern PageCharacteristics page_characteristics;
// Ability to name anonymous VMAs is available on some, but not all Linux-based
// systems.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
#if PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_LINUX)
#include <sys/prctl.h>
#if defined(PR_SET_VMA) && defined(PR_SET_VMA_ANON_NAME)
#define LINUX_NAME_REGION 1
#endif
#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
#endif // PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_LINUX)
namespace partition_alloc {
namespace internal {
@@ -86,15 +86,15 @@ PageAllocationGranularity();
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
PageAllocationGranularityShift() {
#if BUILDFLAG(IS_WIN) || defined(ARCH_CPU_PPC64)
#if PA_BUILDFLAG(IS_WIN) || PA_BUILDFLAG(PA_ARCH_CPU_PPC64)
// Modern ppc64 systems support 4kB (shift = 12) and 64kB (shift = 16) page
// sizes. Since 64kB is the de facto standard on the platform and binaries
// compiled for 64kB are likely to work on 4kB systems, 64kB is a good choice
// here.
return 16; // 64kB
#elif defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_LOONGARCH64)
#elif defined(_MIPS_ARCH_LOONGSON) || PA_BUILDFLAG(PA_ARCH_CPU_LOONGARCH64)
return 14; // 16kB
#elif BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS)
#elif PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
return static_cast<size_t>(vm_page_shift);
#elif defined(PARTITION_ALLOCATOR_CONSTANTS_POSIX_NONCONST_PAGE_SIZE)
// arm64 supports 4kb (shift = 12), 16kb (shift = 14), and 64kb (shift = 16)
@@ -113,7 +113,7 @@ PageAllocationGranularityShift() {
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
PageAllocationGranularity() {
#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS)
#if PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
// This is literally equivalent to |1 << PageAllocationGranularityShift()|
// below, but was separated out for IS_APPLE to avoid << on a non-constexpr.
return vm_page_size;
@@ -146,7 +146,7 @@ SystemPageShift() {
// On Windows allocation granularity is higher than the page size. This comes
// into play when reserving address space range (allocation granularity),
// compared to committing pages into memory (system page granularity).
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
return 12; // 4096=1<<12
#else
return PageAllocationGranularityShift();
@@ -155,7 +155,7 @@ SystemPageShift() {
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
SystemPageSize() {
#if (BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS)) || \
#if (PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)) || \
defined(PARTITION_ALLOCATOR_CONSTANTS_POSIX_NONCONST_PAGE_SIZE)
// This is literally equivalent to |1 << SystemPageShift()| below, but was
// separated out for 64-bit IS_APPLE and arm64 on Android/Linux to avoid <<
@@ -23,11 +23,11 @@
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/thread_isolation/thread_isolation.h"
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
#include "partition_alloc/partition_alloc_base/apple/foundation_util.h"
#if BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(IS_IOS)
#include "partition_alloc/partition_alloc_base/ios/ios_util.h"
#elif BUILDFLAG(IS_MAC)
#elif PA_BUILDFLAG(IS_MAC)
#include "partition_alloc/partition_alloc_base/mac/mac_util.h"
#else
#error "Unknown platform"
@@ -38,10 +38,10 @@
#include <Security/Security.h>
#include <mach/mach.h>
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
#if PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_LINUX)
#include <sys/prctl.h>
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
#include <sys/resource.h>
#endif
@@ -49,7 +49,7 @@
#define MAP_ANONYMOUS MAP_ANON
#endif
#if BUILDFLAG(IS_MAC)
#if PA_BUILDFLAG(IS_MAC)
// SecTaskGetCodeSignStatus is marked as unavailable on macOS, although its
// available on iOS and other Apple operating systems. It is, in fact, present
@@ -59,7 +59,7 @@
uint32_t SecTaskGetCodeSignStatus(SecTaskRef task) API_AVAILABLE(macos(10.12));
#pragma clang diagnostic pop
#endif // BUILDFLAG(IS_MAC)
#endif // PA_BUILDFLAG(IS_MAC)
namespace partition_alloc::internal {
@@ -102,7 +102,7 @@ void NameRegion(void* start, size_t length, PageTag page_tag) {
#endif // defined(LINUX_NAME_REGION)
#if BUILDFLAG(IS_MAC)
#if PA_BUILDFLAG(IS_MAC)
// Tests whether the version of macOS supports the MAP_JIT flag and if the
// current process is signed with the hardened runtime and the allow-jit
// entitlement, returning whether MAP_JIT should be used to allocate regions
@@ -144,7 +144,7 @@ bool UseMapJit() {
return base::apple::CFCast<CFBooleanRef>(jit_entitlement.get()) ==
kCFBooleanTrue;
}
#elif BUILDFLAG(IS_IOS)
#elif PA_BUILDFLAG(IS_IOS)
bool UseMapJit() {
// Always enable MAP_JIT in simulator as it is supported unconditionally.
#if TARGET_IPHONE_SIMULATOR
@@ -155,7 +155,7 @@ bool UseMapJit() {
return false;
#endif // TARGET_IPHONE_SIMULATOR
}
#endif // BUILDFLAG(IS_IOS)
#endif // PA_BUILDFLAG(IS_IOS)
} // namespace
// |mmap| uses a nearby address if the hint address is blocked.
@@ -169,7 +169,7 @@ uintptr_t SystemAllocPagesInternal(uintptr_t hint,
PageAccessibilityConfiguration accessibility,
PageTag page_tag,
int file_descriptor_for_shared_alloc) {
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
// Use a custom tag to make it easier to distinguish PartitionAlloc regions
// in vmmap(1). Tags between 240-255 are supported.
int fd = file_descriptor_for_shared_alloc == -1
@@ -182,7 +182,7 @@ uintptr_t SystemAllocPagesInternal(uintptr_t hint,
int access_flag = GetAccessFlags(accessibility);
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
// On macOS, executables that are code signed with the "runtime" option cannot
// execute writable memory by default. They can opt into this capability by
// specifying the "com.apple.security.cs.allow-jit" code signing entitlement
@@ -336,7 +336,7 @@ bool DecommitAndZeroSystemPagesInternal(uintptr_t address,
size_t length,
PageTag page_tag) {
int fd = -1;
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
fd = VM_MAKE_TAG(static_cast<int>(page_tag));
#endif
@@ -377,7 +377,7 @@ void RecommitSystemPagesInternal(
SetSystemPagesAccess(address, length, accessibility);
}
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
// On macOS, to update accounting, we need to make another syscall. For more
// details, see https://crbug.com/823915.
madvise(reinterpret_cast<void*>(address), length, MADV_FREE_REUSE);
@@ -400,7 +400,7 @@ bool TryRecommitSystemPagesInternal(
}
}
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
// On macOS, to update accounting, we need to make another syscall. For more
// details, see https://crbug.com/823915.
madvise(reinterpret_cast<void*>(address), length, MADV_FREE_REUSE);
@@ -411,7 +411,7 @@ bool TryRecommitSystemPagesInternal(
void DiscardSystemPagesInternal(uintptr_t address, size_t length) {
void* ptr = reinterpret_cast<void*>(address);
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
int ret = madvise(ptr, length, MADV_FREE_REUSABLE);
if (ret) {
// MADV_FREE_REUSABLE sometimes fails, so fall back to MADV_DONTNEED.
@@ -421,7 +421,7 @@ void DiscardSystemPagesInternal(uintptr_t address, size_t length) {
#elif defined(NO_MADVISE_SYSCALL)
static_cast<void>(ptr);
static_cast<void>(length);
#else // BUILDFLAG(IS_APPLE)
#else // PA_BUILDFLAG(IS_APPLE)
// We have experimented with other flags, but with suboptimal results.
//
// MADV_FREE (Linux): Makes our memory measurements less predictable;
@@ -429,7 +429,7 @@ void DiscardSystemPagesInternal(uintptr_t address, size_t length) {
//
// Therefore, we just do the simple thing: MADV_DONTNEED.
PA_PCHECK(0 == madvise(ptr, length, MADV_DONTNEED));
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
}
} // namespace partition_alloc::internal
@@ -23,13 +23,13 @@
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/thread_isolation/thread_isolation.h"
#if BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(IS_IOS)
#include <mach-o/dyld.h>
#endif
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
#if PA_CONFIG(ENABLE_SHADOW_METADATA) || PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
#include <sys/mman.h>
@@ -41,7 +41,7 @@ namespace partition_alloc::internal {
namespace {
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
PA_NOINLINE void HandlePoolAllocFailureOutOfVASpace() {
PA_NO_CODE_FOLDING();
@@ -52,7 +52,7 @@ PA_NOINLINE void HandlePoolAllocFailureOutOfCommitCharge() {
PA_NO_CODE_FOLDING();
PA_CHECK(false);
}
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
PA_NOINLINE void HandlePoolAllocFailure() {
PA_NO_CODE_FOLDING();
@@ -60,7 +60,7 @@ PA_NOINLINE void HandlePoolAllocFailure() {
PA_DEBUG_DATA_ON_STACK("error", static_cast<size_t>(alloc_page_error_code));
// It's important to easily differentiate these two failures on Windows, so
// crash with different stacks.
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
if (alloc_page_error_code == ERROR_NOT_ENOUGH_MEMORY) {
// The error code says NOT_ENOUGH_MEMORY, but since we only do MEM_RESERVE,
// it must be VA space exhaustion.
@@ -72,7 +72,7 @@ PA_NOINLINE void HandlePoolAllocFailure() {
// amount per 64kiB block. Keep this path anyway, to check in crash reports.
HandlePoolAllocFailureOutOfCommitCharge();
} else
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
{
PA_CHECK(false);
}
@@ -85,10 +85,19 @@ PartitionAddressSpace::PoolSetup PartitionAddressSpace::setup_;
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
std::ptrdiff_t PartitionAddressSpace::regular_pool_shadow_offset_ = 0;
std::ptrdiff_t PartitionAddressSpace::brp_pool_shadow_offset_ = 0;
#endif
std::ptrdiff_t PartitionAddressSpace::configurable_pool_shadow_offset_ = 0;
// File descriptors for shared mappings.
int PartitionAddressSpace::regular_pool_fd_ = -1;
int PartitionAddressSpace::brp_pool_fd_ = -1;
int PartitionAddressSpace::configurable_pool_fd_ = -1;
uintptr_t PartitionAddressSpace::pool_shadow_address_ =
PartitionAddressSpace::kUninitializedPoolBaseAddress;
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
#if PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)
#if !BUILDFLAG(IS_IOS)
#if !PA_BUILDFLAG(IS_IOS)
#error Dynamic pool size is only supported on iOS.
#endif
@@ -135,13 +144,27 @@ PA_ALWAYS_INLINE size_t PartitionAddressSpace::BRPPoolSize() {
}
#endif // PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
size_t PartitionAddressSpace::RegularPoolShadowSize() {
return (RegularPoolSize() >> kSuperPageShift) << SystemPageShift();
}
size_t PartitionAddressSpace::BRPPoolShadowSize() {
return (BRPPoolSize() >> kSuperPageShift) << SystemPageShift();
}
size_t PartitionAddressSpace::ConfigurablePoolShadowSize() {
return (kConfigurablePoolMaxSize >> kSuperPageShift) << SystemPageShift();
}
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
void PartitionAddressSpace::Init() {
if (IsInitialized()) {
return;
}
size_t regular_pool_size = RegularPoolSize();
size_t brp_pool_size = BRPPoolSize();
const size_t regular_pool_size = RegularPoolSize();
const size_t brp_pool_size = BRPPoolSize();
#if PA_BUILDFLAG(GLUE_CORE_POOLS)
// Gluing core pools (regular & BRP) makes sense only when both pools are of
@@ -166,25 +189,15 @@ void PartitionAddressSpace::Init() {
setup_.brp_pool_base_address_ =
setup_.regular_pool_base_address_ + regular_pool_size;
#else // PA_BUILDFLAG(GLUE_CORE_POOLS)
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
int regular_pool_fd = memfd_create("/regular_pool", MFD_CLOEXEC);
#else
int regular_pool_fd = -1;
#endif
setup_.regular_pool_base_address_ =
AllocPages(regular_pool_size, regular_pool_size,
PageAccessibilityConfiguration(
PageAccessibilityConfiguration::kInaccessible),
PageTag::kPartitionAlloc, regular_pool_fd);
PageTag::kPartitionAlloc);
if (!setup_.regular_pool_base_address_) {
HandlePoolAllocFailure();
}
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
int brp_pool_fd = memfd_create("/brp_pool", MFD_CLOEXEC);
#else
int brp_pool_fd = -1;
#endif
// Reserve an extra allocation granularity unit before the BRP pool, but keep
// the pool aligned at BRPPoolSize(). A pointer immediately past an allocation
// is a valid pointer, and having a "forbidden zone" before the BRP pool
@@ -195,7 +208,7 @@ void PartitionAddressSpace::Init() {
brp_pool_size - kForbiddenZoneSize,
PageAccessibilityConfiguration(
PageAccessibilityConfiguration::kInaccessible),
PageTag::kPartitionAlloc, brp_pool_fd);
PageTag::kPartitionAlloc, -1);
if (!base_address) {
HandlePoolAllocFailure();
}
@@ -260,26 +273,6 @@ void PartitionAddressSpace::Init() {
"the regular pool";
#endif // PA_CONFIG(STARSCAN_USE_CARD_TABLE)
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
// Reserve memory for the shadow pools.
uintptr_t regular_pool_shadow_address =
AllocPages(regular_pool_size, regular_pool_size,
PageAccessibilityConfiguration(
PageAccessibilityConfiguration::kInaccessible),
PageTag::kPartitionAlloc, regular_pool_fd);
regular_pool_shadow_offset_ =
regular_pool_shadow_address - setup_.regular_pool_base_address_;
uintptr_t brp_pool_shadow_address = AllocPagesWithAlignOffset(
0, brp_pool_size + kForbiddenZoneSize, brp_pool_size,
brp_pool_size - kForbiddenZoneSize,
PageAccessibilityConfiguration(
PageAccessibilityConfiguration::kInaccessible),
PageTag::kPartitionAlloc, brp_pool_fd);
brp_pool_shadow_offset_ =
brp_pool_shadow_address - setup_.brp_pool_base_address_;
#endif
#if PA_BUILDFLAG(ENABLE_POINTER_COMPRESSION)
CompressedPointerBaseGlobal::SetBase(setup_.regular_pool_base_address_);
#endif // PA_BUILDFLAG(ENABLE_POINTER_COMPRESSION)
@@ -421,6 +414,195 @@ void PartitionAddressSpace::UninitThreadIsolatedPoolForTesting() {
}
#endif
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
namespace {
int CreateAnonymousFileForMapping([[maybe_unused]] const char* name,
[[maybe_unused]] size_t size) {
int fd = -1;
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
// TODO(crbug.com/40238514): if memfd_secret() is available, try
// memfd_secret() first.
fd = memfd_create(name, MFD_CLOEXEC);
PA_CHECK(0 == ftruncate(fd, size));
#else
// Not implemented yet.
PA_NOTREACHED();
#endif // PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
return fd;
}
} // namespace
void PartitionAddressSpace::InitShadowMetadata(PoolHandleMask mask) {
// Set up an address space only once.
if (pool_shadow_address_ == kUninitializedPoolBaseAddress) {
// Reserve 1 address space for all pools.
const size_t shadow_pool_size =
std::max(ConfigurablePoolShadowSize(),
std::max(RegularPoolShadowSize(), BRPPoolShadowSize()));
// Reserve virtual address space for the shadow pool.
uintptr_t pool_shadow_address =
AllocPages(shadow_pool_size, PageAllocationGranularity(),
PageAccessibilityConfiguration(
PageAccessibilityConfiguration::kInaccessible),
PageTag::kPartitionAlloc);
if (!pool_shadow_address) {
HandlePoolAllocFailure();
}
pool_shadow_address_ = pool_shadow_address;
}
// Set up a memory file for the given pool, and init |offset|.
if (ContainsFlags(mask, PoolHandleMask::kConfigurable)) {
if (configurable_pool_fd_ == -1) {
PA_DCHECK(pool_shadow_address_);
PA_DCHECK(configurable_pool_shadow_offset_ == 0);
configurable_pool_fd_ = CreateAnonymousFileForMapping(
"configurable_pool_shadow", ConfigurablePoolShadowSize());
configurable_pool_shadow_offset_ =
pool_shadow_address_ - ConfigurablePoolBase() +
SystemPageSize() * kSystemPageOffsetOfConfigurablePoolShadow;
}
}
if (ContainsFlags(mask, PoolHandleMask::kBRP)) {
if (brp_pool_fd_ == -1) {
PA_DCHECK(pool_shadow_address_);
PA_DCHECK(brp_pool_shadow_offset_ == 0);
brp_pool_fd_ =
CreateAnonymousFileForMapping("brp_pool_shadow", BRPPoolShadowSize());
brp_pool_shadow_offset_ =
pool_shadow_address_ - BRPPoolBase() +
SystemPageSize() * kSystemPageOffsetOfBRPPoolShadow;
}
}
if (ContainsFlags(mask, PoolHandleMask::kRegular)) {
if (regular_pool_fd_ == -1) {
PA_DCHECK(pool_shadow_address_);
PA_DCHECK(regular_pool_shadow_offset_ == 0);
regular_pool_fd_ = CreateAnonymousFileForMapping("regular_pool_shadow",
RegularPoolShadowSize());
regular_pool_shadow_offset_ =
pool_shadow_address_ - RegularPoolBase() +
SystemPageSize() * kSystemPageOffsetOfRegularPoolShadow;
}
}
}
// Share a read-only metadata inside the given SuperPage with its writable
// metadata.
void PartitionAddressSpace::MapMetadata(uintptr_t super_page,
bool copy_metadata) {
PA_DCHECK(pool_shadow_address_);
PA_DCHECK(0u == (super_page & kSuperPageOffsetMask));
std::ptrdiff_t offset;
int pool_fd = -1;
uintptr_t base_address;
if (IsInRegularPool(super_page)) {
pool_fd = regular_pool_fd_;
offset = regular_pool_shadow_offset_;
base_address = RegularPoolBase();
} else if (IsInBRPPool(super_page)) {
offset = brp_pool_shadow_offset_;
pool_fd = brp_pool_fd_;
base_address = BRPPoolBase();
} else if (IsInConfigurablePool(super_page)) {
offset = configurable_pool_shadow_offset_;
pool_fd = configurable_pool_fd_;
base_address = ConfigurablePoolBase();
} else {
PA_NOTREACHED();
}
uintptr_t metadata = super_page + SystemPageSize();
size_t file_offset = (super_page - base_address) >> kSuperPageShift
<< SystemPageShift();
#if PA_BUILDFLAG(IS_POSIX)
uintptr_t writable_metadata = metadata + offset;
void* ptr = mmap(reinterpret_cast<void*>(writable_metadata), SystemPageSize(),
PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, pool_fd,
file_offset);
PA_CHECK(ptr != MAP_FAILED);
PA_CHECK(ptr == reinterpret_cast<void*>(writable_metadata));
if (PA_UNLIKELY(copy_metadata)) {
// Copy the metadata from the private and copy-on-write page to
// the shared page. (=update the memory file)
memcpy(reinterpret_cast<void*>(writable_metadata),
reinterpret_cast<void*>(metadata), SystemPageSize());
}
ptr = mmap(reinterpret_cast<void*>(metadata), SystemPageSize(), PROT_READ,
MAP_FIXED | MAP_SHARED, pool_fd, file_offset);
PA_CHECK(ptr != MAP_FAILED);
PA_CHECK(ptr == reinterpret_cast<void*>(metadata));
#else
// Not implemneted yet.
PA_NOTREACHED();
#endif // PA_BUILDFLAG(IS_POSIX)
}
// Regarding normal buckets, metadata will not be decommitted. However,
// regarding direct-mapped, metadata will be decommitted (see UnmapNow()).
// So shadow metadata must be also decommitted (including zero-initialization).
void PartitionAddressSpace::UnmapShadowMetadata(uintptr_t super_page,
pool_handle pool) {
PA_DCHECK(0u == (super_page & kSuperPageOffsetMask));
std::ptrdiff_t offset;
switch (pool) {
case kRegularPoolHandle:
PA_DCHECK(RegularPoolBase() <= super_page);
PA_DCHECK((super_page - RegularPoolBase()) < RegularPoolSize());
PA_DCHECK(IsShadowMetadataEnabled(kRegularPoolHandle));
offset = regular_pool_shadow_offset_;
break;
case kBRPPoolHandle:
PA_DCHECK(BRPPoolBase() <= super_page);
PA_DCHECK((super_page - BRPPoolBase()) < BRPPoolSize());
PA_DCHECK(IsShadowMetadataEnabled(kBRPPoolHandle));
offset = brp_pool_shadow_offset_;
break;
case kConfigurablePoolHandle:
PA_DCHECK(IsShadowMetadataEnabled(kConfigurablePoolHandle));
offset = configurable_pool_shadow_offset_;
break;
default:
return;
}
uintptr_t writable_metadata = super_page + SystemPageSize() + offset;
void* ptr = reinterpret_cast<void*>(writable_metadata);
// When mapping the page again, we will use mmap() with MAP_FIXED |
// MAP_SHARED. Not with MAP_ANONYMOUS. If we don't clear the page here, the
// page will have the same content when re-mapped.
// TODO(crbug.com/40238514): Make PartitionAlloc not depend on that metadata
// pages have been already initialized to be zero. i.e. remove memset() below
// and make the constructors of SlotSpanMetadata, PartitionPageMetadata (and
// more struct/class if needed) initialize their members. Add test to check
// if the initialization is correctly done.
memset(ptr, 0, SystemPageSize());
#if PA_BUILDFLAG(IS_POSIX)
void* ret = mmap(ptr, SystemPageSize(), PROT_NONE,
MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
PA_CHECK(ret != MAP_FAILED);
PA_CHECK(ret == ptr);
#else
// Not implemented yet.
PA_NOTREACHED();
#endif // PA_BUILDFLAG(IS_POSIX)
}
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
#if defined(PARTITION_ALLOCATOR_CONSTANTS_POSIX_NONCONST_PAGE_SIZE)
PageCharacteristics page_characteristics;
@@ -172,6 +172,16 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAddressSpace {
return (address & brp_pool_base_mask) == setup_.brp_pool_base_address_;
}
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
PA_ALWAYS_INLINE static uintptr_t BRPPoolBase() {
#if PA_BUILDFLAG(GLUE_CORE_POOLS)
return RegularPoolBase() + RegularPoolSize();
#else
return setup_.brp_pool_base_address_;
#endif // PA_BUILDFLAG(GLUE_CORE_POOLS)
}
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
#if PA_BUILDFLAG(GLUE_CORE_POOLS)
// Checks whether the address belongs to either regular or BRP pool.
// Returns false for nullptr.
@@ -224,19 +234,106 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAddressSpace {
#endif
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
PA_ALWAYS_INLINE static std::ptrdiff_t ShadowPoolOffset(pool_handle pool) {
if (pool == kRegularPoolHandle) {
return regular_pool_shadow_offset_;
} else if (pool == kBRPPoolHandle) {
return brp_pool_shadow_offset_;
} else {
// TODO(crbug.com/40238514): Add shadow for configurable pool as well.
// Shadow is not created for ConfigurablePool for now, so this part should
// be unreachable.
PA_NOTREACHED();
PA_ALWAYS_INLINE static bool IsShadowMetadataEnabledOnRegularPool() {
return regular_pool_fd_ != -1;
}
PA_ALWAYS_INLINE static bool IsShadowMetadataEnabledOnBRPPool() {
return brp_pool_fd_ != -1;
}
PA_ALWAYS_INLINE static bool IsShadowMetadataEnabledOnConfigurablePool() {
return configurable_pool_fd_ != -1;
}
PA_ALWAYS_INLINE static bool IsShadowMetadataEnabled(pool_handle pool) {
switch (pool) {
case kRegularPoolHandle:
return IsShadowMetadataEnabledOnRegularPool();
case kBRPPoolHandle:
return IsShadowMetadataEnabledOnBRPPool();
case kConfigurablePoolHandle:
return IsShadowMetadataEnabledOnConfigurablePool();
default:
return false;
}
}
#endif
// To reduce the cost of address conversion (metadata address inside Regular
// Pool to its shadow metadata address), we will make the size of the address
// space of shadow metadata the same as `max(regular pool size, brp
// pool size, configurable pool size)` (only 1 shadow address space. Not 3)
// So we need to use different offset for metadata of the regular pool's
// SuperPages and for the brp pool's SuperPages.
// i.e. |kSystemPageOffsetOfRegularPoolShadow| and
// |kSystemPageOffsetOfBRPPoolShadow|.
//
// i: the index of SystemPage for metadata inside the regular pool's
// SuperPage.
// (currently, the index is 1.)
//
// i-th
// +------------+
// | SystemPage | (regular pool)
// +------------+
// \
// \ mapping
// \
// (i+kSystemPageOffsetOfRegularPoolShadow)-th
// +------------+
// | SystemPage | (shadow)
// +------------+
//
// (i + kSystemPageOffsetOfRegularPoolShadow)-th SystemPage inside the matched
// SuperPage inside the shadow pool is used for the metadata.
static constexpr size_t kSystemPageOffsetOfRegularPoolShadow = 0u;
static constexpr size_t kSystemPageOffsetOfBRPPoolShadow = 2u;
static constexpr size_t kSystemPageOffsetOfConfigurablePoolShadow = 4u;
static size_t RegularPoolShadowSize();
static size_t BRPPoolShadowSize();
static size_t ConfigurablePoolShadowSize();
PA_ALWAYS_INLINE static std::ptrdiff_t RegularPoolShadowOffset() {
return regular_pool_shadow_offset_;
}
PA_ALWAYS_INLINE static std::ptrdiff_t BRPPoolShadowOffset() {
return brp_pool_shadow_offset_;
}
PA_ALWAYS_INLINE static std::ptrdiff_t ConfigurablePoolShadowOffset() {
return configurable_pool_shadow_offset_;
}
// TODO(crbug.com/40238514): Confirm we can use kConfigurablePoolMaxSize/4
// for iOS and confirm iOS EarlyGrey tests pass when the shadow metadata
// is enabled, since IIRC iOS limits virtual address space too.
static_assert(
!PA_BUILDFLAG(IS_IOS),
"kConfigurablePoolMaxSize is too large to run iOS EarlyGrey tests, "
"because the test process cannot use an extended virtual address space. "
"Temporarily disable ShadowMetadata feature on iOS");
#if PA_BUILDFLAG(PA_DCHECK_IS_ON)
// Check whether the given |ptr| points to an address inside the address space
// reserved for the regular and brp shadow. However the result |true| doesn't
// mean the given |ptr| is valid. Because we don't use the entire address
// space for the shadow. We only use 2 SystemPageSize() / kSuperPageSize(%)
// of the space. See PoolShadowOffset().
PA_ALWAYS_INLINE static bool IsInPoolShadow(const void* ptr) {
uintptr_t ptr_as_uintptr = reinterpret_cast<uintptr_t>(ptr);
return (pool_shadow_address_ <= ptr_as_uintptr &&
(ptr_as_uintptr < pool_shadow_address_ + RegularPoolSize() ||
ptr_as_uintptr < pool_shadow_address_ + BRPPoolSize() ||
ptr_as_uintptr < pool_shadow_address_ + kConfigurablePoolMaxSize));
}
#endif // PA_BUILDFLAG(PA_DCHECK_IS_ON)
static void InitShadowMetadata(PoolHandleMask pool);
static void MapMetadata(uintptr_t super_page, bool copy_metadata);
static void UnmapShadowMetadata(uintptr_t super_page, pool_handle pool);
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
// PartitionAddressSpace is static_only class.
PartitionAddressSpace() = delete;
@@ -297,7 +394,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAddressSpace {
static_assert(std::has_single_bit(kConfigurablePoolMaxSize));
static_assert(std::has_single_bit(kConfigurablePoolMinSize));
#if BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(IS_IOS)
#if !PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)
#error iOS is only supported with a dynamically sized GigaCase.
@@ -312,7 +409,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAddressSpace {
static_assert(kBRPPoolSizeForIOSTestProcess < kBRPPoolSize);
static_assert(std::has_single_bit(kRegularPoolSizeForIOSTestProcess));
static_assert(std::has_single_bit(kBRPPoolSizeForIOSTestProcess));
#endif // BUILDFLAG(IOS_IOS)
#endif // PA_BUILDFLAG(IOS_IOS)
#if !PA_CONFIG(DYNAMICALLY_SELECT_POOL_SIZE)
// Masks used to easy determine belonging to a pool.
@@ -380,7 +477,13 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAddressSpace {
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
static std::ptrdiff_t regular_pool_shadow_offset_;
static std::ptrdiff_t brp_pool_shadow_offset_;
#endif
static std::ptrdiff_t configurable_pool_shadow_offset_;
// TODO(crbug.com/40238514): Use platform file handles instead of |int|.
static int regular_pool_fd_;
static int brp_pool_fd_;
static int configurable_pool_fd_;
static uintptr_t pool_shadow_address_;
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
#if PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
// If we use thread isolation, we need to write-protect its metadata.
@@ -402,12 +505,6 @@ PA_ALWAYS_INLINE uintptr_t OffsetInBRPPool(uintptr_t address) {
return PartitionAddressSpace::OffsetInBRPPool(address);
}
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
PA_ALWAYS_INLINE std::ptrdiff_t ShadowPoolOffset(pool_handle pool) {
return PartitionAddressSpace::ShadowPoolOffset(pool);
}
#endif
} // namespace internal
// Returns false for nullptr.
@@ -18,12 +18,18 @@
#include "partition_alloc/thread_isolation/thread_isolation.h"
// Prefetch *x into memory.
#if defined(__clang__) || defined(COMPILER_GCC)
#define PA_PREFETCH(x) __builtin_prefetch(x)
#if defined(__clang__) || PA_BUILDFLAG(PA_COMPILER_GCC)
#define PA_PREFETCH(x) __builtin_prefetch(x, 0)
#else
#define PA_PREFETCH(x)
#endif
#if defined(__clang__) || PA_BUILDFLAG(PA_COMPILER_GCC)
#define PA_PREFETCH_FOR_WRITE(x) __builtin_prefetch(x, 1)
#else
#define PA_PREFETCH_FOR_WRITE(x)
#endif
namespace partition_alloc::internal {
// This is a `memset` that resists being optimized away. Adapted from
@@ -73,11 +73,11 @@ CheckError::~CheckError() {
if (!has_errno) {
log_message_.~LogMessage();
} else {
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
errno_log_message_.~Win32ErrorLogMessage();
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
errno_log_message_.~ErrnoLogMessage();
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
}
}
@@ -93,7 +93,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) CheckError {
union {
LogMessage log_message_;
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
Win32ErrorLogMessage errno_log_message_;
#else
ErrnoLogMessage errno_log_message_;
@@ -33,9 +33,9 @@
// NOINLINE void DoStuff() { ... }
#if defined(__clang__) && PA_HAS_ATTRIBUTE(noinline)
#define PA_NOINLINE [[clang::noinline]]
#elif defined(COMPILER_GCC) && PA_HAS_ATTRIBUTE(noinline)
#elif PA_BUILDFLAG(PA_COMPILER_GCC) && PA_HAS_ATTRIBUTE(noinline)
#define PA_NOINLINE __attribute__((noinline))
#elif defined(COMPILER_MSVC)
#elif PA_BUILDFLAG(PA_COMPILER_MSVC)
#define PA_NOINLINE __declspec(noinline)
#else
#define PA_NOINLINE
@@ -43,10 +43,10 @@
#if defined(__clang__) && defined(NDEBUG) && PA_HAS_ATTRIBUTE(always_inline)
#define PA_ALWAYS_INLINE [[clang::always_inline]] inline
#elif defined(COMPILER_GCC) && defined(NDEBUG) && \
#elif PA_BUILDFLAG(PA_COMPILER_GCC) && defined(NDEBUG) && \
PA_HAS_ATTRIBUTE(always_inline)
#define PA_ALWAYS_INLINE inline __attribute__((__always_inline__))
#elif defined(COMPILER_MSVC) && defined(NDEBUG)
#elif PA_BUILDFLAG(PA_COMPILER_MSVC) && defined(NDEBUG)
#define PA_ALWAYS_INLINE __forceinline
#else
#define PA_ALWAYS_INLINE inline
@@ -78,9 +78,9 @@
// may be that this macro can be removed entirely.
#if defined(__clang__)
#define PA_ALIGNAS(byte_alignment) alignas(byte_alignment)
#elif defined(COMPILER_MSVC)
#elif PA_BUILDFLAG(PA_COMPILER_MSVC)
#define PA_ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
#elif defined(COMPILER_GCC) && PA_HAS_ATTRIBUTE(aligned)
#elif PA_BUILDFLAG(PA_COMPILER_GCC) && PA_HAS_ATTRIBUTE(aligned)
#define PA_ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#endif
@@ -92,7 +92,8 @@
// References:
// * https://en.cppreference.com/w/cpp/language/attributes/no_unique_address
// * https://wg21.link/dcl.attr.nouniqueaddr
#if defined(COMPILER_MSVC) && PA_HAS_CPP_ATTRIBUTE(msvc::no_unique_address)
#if PA_BUILDFLAG(PA_COMPILER_MSVC) && \
PA_HAS_CPP_ATTRIBUTE(msvc::no_unique_address)
// Unfortunately MSVC ignores [[no_unique_address]] (see
// https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/#msvc-extensions-and-abi),
// and clang-cl matches it for ABI compatibility reasons. We need to prefer
@@ -110,7 +111,8 @@
// For v*printf functions (which take a va_list), pass 0 for dots_param.
// (This is undocumented but matches what the system C headers do.)
// For member functions, the implicit this parameter counts as index 1.
#if (defined(COMPILER_GCC) || defined(__clang__)) && PA_HAS_ATTRIBUTE(format)
#if (PA_BUILDFLAG(PA_COMPILER_GCC) || defined(__clang__)) && \
PA_HAS_ATTRIBUTE(format)
#define PA_PRINTF_FORMAT(format_param, dots_param) \
__attribute__((format(printf, format_param, dots_param)))
#else
@@ -139,19 +141,19 @@
// Macro for hinting that an expression is likely to be false.
#if !defined(PA_UNLIKELY)
#if defined(COMPILER_GCC) || defined(__clang__)
#if PA_BUILDFLAG(PA_COMPILER_GCC) || defined(__clang__)
#define PA_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define PA_UNLIKELY(x) (x)
#endif // defined(COMPILER_GCC)
#endif // PA_BUILDFLAG(PA_COMPILER_GCC)
#endif // !defined(PA_UNLIKELY)
#if !defined(PA_LIKELY)
#if defined(COMPILER_GCC) || defined(__clang__)
#if PA_BUILDFLAG(PA_COMPILER_GCC) || defined(__clang__)
#define PA_LIKELY(x) __builtin_expect(!!(x), 1)
#else
#define PA_LIKELY(x) (x)
#endif // defined(COMPILER_GCC)
#endif // PA_BUILDFLAG(PA_COMPILER_GCC)
#endif // !defined(PA_LIKELY)
// Compiler feature-detection.
@@ -15,27 +15,28 @@
#include "partition_alloc/build_config.h"
#if defined(ARCH_CPU_ARM_FAMILY) && \
(BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM_FAMILY) && \
(PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_LINUX) || \
PA_BUILDFLAG(IS_CHROMEOS))
#include <asm/hwcap.h>
#include <sys/auxv.h>
// Temporary definitions until a new hwcap.h is pulled in everywhere.
// https://crbug.com/1265965
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
#ifndef HWCAP2_MTE
#define HWCAP2_MTE (1 << 18)
#endif
#ifndef HWCAP2_BTI
#define HWCAP2_BTI (1 << 17)
#endif
#endif // # defined(ARCH_CPU_ARM64)
#endif // PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
#endif // defined(ARCH_CPU_ARM_FAMILY) && (BUILDFLAG(IS_ANDROID) ||
// BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
#endif // PA_BUILDFLAG(PA_ARCH_CPU_ARM_FAMILY) && (PA_BUILDFLAG(IS_ANDROID) ||
// PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS))
#if defined(ARCH_CPU_X86_FAMILY)
#if defined(COMPILER_MSVC)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
#if PA_BUILDFLAG(PA_COMPILER_MSVC)
#include <immintrin.h> // For _xgetbv()
#include <intrin.h>
#endif
@@ -50,8 +51,8 @@ CPU::CPU(CPU&&) = default;
namespace {
#if defined(ARCH_CPU_X86_FAMILY)
#if !defined(COMPILER_MSVC)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
#if !PA_BUILDFLAG(PA_COMPILER_MSVC)
#if defined(__pic__) && defined(__i386__)
@@ -75,19 +76,19 @@ void __cpuid(int cpu_info[4], int info_type) {
}
#endif
#endif // !defined(COMPILER_MSVC)
#endif // !PA_BUILDFLAG(PA_COMPILER_MSVC)
// xgetbv returns the value of an Intel Extended Control Register (XCR).
// Currently only XCR0 is defined by Intel so |xcr| should always be zero.
uint64_t xgetbv(uint32_t xcr) {
#if defined(COMPILER_MSVC)
#if PA_BUILDFLAG(PA_COMPILER_MSVC)
return _xgetbv(xcr);
#else
uint32_t eax, edx;
__asm__ volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr));
return (static_cast<uint64_t>(edx) << 32) | eax;
#endif // defined(COMPILER_MSVC)
#endif // PA_BUILDFLAG(PA_COMPILER_MSVC)
}
#endif // ARCH_CPU_X86_FAMILY
@@ -95,7 +96,7 @@ uint64_t xgetbv(uint32_t xcr) {
} // namespace
void CPU::Initialize() {
#if defined(ARCH_CPU_X86_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
int cpu_info[4] = {-1};
// __cpuid with an InfoType argument of 0 returns the number of
@@ -182,17 +183,18 @@ void CPU::Initialize() {
has_non_stop_time_stamp_counter_ = true;
}
}
#elif defined(ARCH_CPU_ARM_FAMILY)
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#elif PA_BUILDFLAG(PA_ARCH_CPU_ARM_FAMILY)
#if PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_LINUX) || \
PA_BUILDFLAG(IS_CHROMEOS)
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// Check for Armv8.5-A BTI/MTE support, exposed via HWCAP2
unsigned long hwcap2 = getauxval(AT_HWCAP2);
has_mte_ = hwcap2 & HWCAP2_MTE;
has_bti_ = hwcap2 & HWCAP2_BTI;
#endif
#elif BUILDFLAG(IS_WIN)
#elif PA_BUILDFLAG(IS_WIN)
// Windows makes high-resolution thread timing information available in
// user-space.
has_non_stop_time_stamp_counter_ = true;
@@ -59,7 +59,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) CPU final {
bool is_running_in_vm() const { return is_running_in_vm_; }
// Armv8.5-A extensions for control flow and memory safety.
#if defined(ARCH_CPU_ARM_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM_FAMILY)
bool has_mte() const { return has_mte_; }
bool has_bti() const { return has_bti_; }
#else
@@ -67,7 +67,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) CPU final {
constexpr bool has_bti() const { return false; }
#endif
#if defined(ARCH_CPU_X86_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
// Memory protection key support for user-mode pages
bool has_pku() const { return has_pku_; }
#else
@@ -93,11 +93,11 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) CPU final {
bool has_fma3_ = false;
bool has_avx2_ = false;
bool has_aesni_ = false;
#if defined(ARCH_CPU_ARM_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM_FAMILY)
bool has_mte_ = false; // Armv8.5-A MTE (Memory Taggging Extension)
bool has_bti_ = false; // Armv8.5-A BTI (Branch Target Identification)
#endif
#if defined(ARCH_CPU_X86_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
bool has_pku_ = false;
#endif
bool has_non_stop_time_stamp_counter_ = false;
@@ -12,7 +12,7 @@
#include "partition_alloc/partition_alloc_base/process/process_handle.h"
#include "partition_alloc/partition_alloc_base/threading/platform_thread.h"
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(__GLIBC__)
#if (PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)) && defined(__GLIBC__)
extern "C" void* __libc_stack_end;
#endif
@@ -35,7 +35,7 @@ constexpr size_t kStackFrameAdjustment = 0;
// Because the signature size can vary based on the system configuration, use
// the xpaclri instruction to remove the signature.
static uintptr_t StripPointerAuthenticationBits(uintptr_t ptr) {
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// A single Chromium binary currently spans all Arm systems (including those
// with and without pointer authentication). xpaclri is used here because it's
// in the HINT space and treated as a no-op on older Arm cores (unlike the
@@ -201,7 +201,7 @@ PA_NOINLINE size_t TraceStackFramePointers(const void** out_trace,
#if PA_BUILDFLAG(PA_CAN_UNWIND_WITH_FRAME_POINTERS)
uintptr_t GetStackEnd() {
#if BUILDFLAG(IS_ANDROID)
#if PA_BUILDFLAG(IS_ANDROID)
// Bionic reads proc/maps on every call to pthread_getattr_np() when called
// from the main thread. So we need to cache end of stack in that case to get
// acceptable performance.
@@ -230,13 +230,13 @@ uintptr_t GetStackEnd() {
main_stack_end = stack_end;
}
return stack_end; // 0 in case of error
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
// No easy way to get end of the stack for non-main threads,
// see crbug.com/617730.
return reinterpret_cast<uintptr_t>(pthread_get_stackaddr_np(pthread_self()));
#else
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(__GLIBC__)
#if (PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)) && defined(__GLIBC__)
if (GetCurrentProcId() == PlatformThread::CurrentId()) {
// For the main thread we have a shortcut.
return reinterpret_cast<uintptr_t>(__libc_stack_end);
@@ -28,7 +28,7 @@ size_t CollectStackTrace(const void** trace, size_t count);
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
void PrintStackTrace(const void** trace, size_t count);
#if BUILDFLAG(IS_POSIX)
#if PA_BUILDFLAG(IS_POSIX)
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
void OutputStackTrace(unsigned index,
uintptr_t address,
@@ -46,7 +46,7 @@ void OutputStackTrace(unsigned index,
// scanning area at the origin of the stack, wasting time and not finding any
// frames (since Android libraries don't have frame pointers). Scanning is not
// enabled on other posix platforms due to legacy reasons.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
constexpr bool kEnableScanningByDefault = true;
#else
constexpr bool kEnableScanningByDefault = false;
@@ -11,7 +11,7 @@
// Surprisingly, uClibc defines __GLIBC__ in some build configs, but
// execinfo.h and backtrace(3) are really only present in glibc and in macOS
// libc.
#if BUILDFLAG(IS_APPLE) || \
#if PA_BUILDFLAG(IS_APPLE) || \
(defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__AIX))
#define HAVE_BACKTRACE
#include <execinfo.h>
@@ -23,7 +23,7 @@ size_t CollectStackTrace(const void** trace, size_t count) {
// NOTE: This code MUST be async-signal safe (it's used by in-process
// stack dumping signal handler). NO malloc or stdio is allowed here.
#if BUILDFLAG(IS_APPLE) && defined(HAVE_BACKTRACE)
#if PA_BUILDFLAG(IS_APPLE) && defined(HAVE_BACKTRACE)
// Regarding Apple, no /proc is available. Try backtrace API.
// Though the backtrace API man page does not list any possible negative
// return values, we take no chance.
@@ -13,11 +13,11 @@
#include "partition_alloc/partition_alloc_base/posix/eintr_wrapper.h"
#include "partition_alloc/partition_alloc_base/strings/safe_sprintf.h"
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_APPLE)
#if !PA_BUILDFLAG(IS_ANDROID) && !PA_BUILDFLAG(IS_APPLE)
#include <link.h> // For ElfW() macro.
#endif
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
#include <dlfcn.h>
#endif
@@ -25,7 +25,7 @@ namespace partition_alloc::internal::base::debug {
namespace {
#if !BUILDFLAG(IS_APPLE)
#if !PA_BUILDFLAG(IS_APPLE)
// On Android the 'open' function has two versions:
// int open(const char *pathname, int flags);
@@ -203,7 +203,7 @@ bool ParseMapsLine(const char* line_start,
return true;
}
#if !BUILDFLAG(IS_ANDROID)
#if !PA_BUILDFLAG(IS_ANDROID)
ssize_t ReadFromOffset(const int fd,
void* buf,
@@ -282,7 +282,7 @@ void UpdateBaseAddress(unsigned permissions,
close(mem_fd);
}
#endif // !BUILDFLAG(IS_ANDROID)
#endif // !PA_BUILDFLAG(IS_ANDROID)
void PrintStackTraceInternal(const void** trace, size_t count) {
int fd = WrapEINTR(OpenFile)("/proc/self/maps", O_RDONLY);
@@ -294,7 +294,7 @@ void PrintStackTraceInternal(const void** trace, size_t count) {
char buffer[kBufferSize];
char* dest = buffer;
char* buffer_end = buffer + kBufferSize;
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_APPLE)
#if !PA_BUILDFLAG(IS_ANDROID) && !PA_BUILDFLAG(IS_APPLE)
uintptr_t base_address = 0u;
#endif
@@ -328,12 +328,12 @@ void PrintStackTraceInternal(const void** trace, size_t count) {
ParseMapsLine(line_start, line_end, &start_address, &end_address,
&permissions, &offset, &module_name);
if (ok) {
#if !BUILDFLAG(IS_ANDROID)
#if !PA_BUILDFLAG(IS_ANDROID)
UpdateBaseAddress(permissions, start_address, &base_address);
#endif
if (module_name && *module_name != '\0') {
for (size_t i = 0; i < count; i++) {
#if BUILDFLAG(IS_ANDROID)
#if PA_BUILDFLAG(IS_ANDROID)
// Subtract one as return address of function may be in the next
// function when a function is annotated as noreturn.
uintptr_t address = reinterpret_cast<uintptr_t>(trace[i]) - 1;
@@ -367,9 +367,9 @@ void PrintStackTraceInternal(const void** trace, size_t count) {
}
close(fd);
}
#endif // !BUILDFLAG(IS_APPLE)
#endif // !PA_BUILDFLAG(IS_APPLE)
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
// Since /proc/self/maps is not available, use dladdr() to obtain module
// names and offsets inside the modules from the given addresses.
void PrintStackTraceInternal(const void* const* trace, size_t size) {
@@ -398,7 +398,7 @@ void PrintStackTraceInternal(const void* const* trace, size_t size) {
}
}
}
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
} // namespace
@@ -407,7 +407,7 @@ void PrintStackTrace(const void** trace, size_t count) {
}
// stack_trace_android.cc defines its own OutputStackTrace.
#if !BUILDFLAG(IS_ANDROID)
#if !PA_BUILDFLAG(IS_ANDROID)
void OutputStackTrace(unsigned index,
uintptr_t address,
uintptr_t base_address,
@@ -418,6 +418,6 @@ void OutputStackTrace(unsigned index,
module_name, address - base_address);
PA_RAW_LOG(INFO, buffer);
}
#endif // !BUILDFLAG(IS_ANDROID)
#endif // !PA_BUILDFLAG(IS_ANDROID)
} // namespace partition_alloc::internal::base::debug
@@ -9,9 +9,9 @@
#include "partition_alloc/partition_alloc_base/check.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#endif
@@ -113,17 +113,17 @@
// enabled and disabled independently, to aid testing. These #defines are
// here so that the same setting can be used in both the implementation and
// in the unit test.
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#define PA_FILE_PATH_USES_DRIVE_LETTERS
#define PA_FILE_PATH_USES_WIN_SEPARATORS
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
// Macros for string literal initialization of FilePath::CharType[].
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#define PA_FILE_PATH_LITERAL(x) L##x
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#define PA_FILE_PATH_LITERAL(x) x
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
namespace partition_alloc::internal::base {
@@ -131,16 +131,16 @@ namespace partition_alloc::internal::base {
// pathnames on different platforms.
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) FilePath {
public:
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// On Windows, for Unicode-aware applications, native pathnames are wchar_t
// arrays encoded in UTF-16.
typedef std::wstring StringType;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// On most platforms, native pathnames are char arrays, and the encoding
// may or may not be specified. On Mac OS X, native pathnames are encoded
// in UTF-8.
typedef std::string StringType;
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
typedef StringType::value_type CharType;
@@ -15,14 +15,14 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#include <sys/stat.h>
#include <unistd.h>
#endif
namespace partition_alloc::internal::base {
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// Read exactly |bytes| bytes from file descriptor |fd|, storing the result
// in |buffer|. This function is protected against EINTR and partial reads.
@@ -30,7 +30,7 @@ namespace partition_alloc::internal::base {
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
bool ReadFromFD(int fd, char* buffer, size_t bytes);
#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#endif // PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
} // namespace partition_alloc::internal::base
@@ -39,9 +39,9 @@
// int3/bkpt/brk will be removed in followups, so splitting it up like this now
// makes it easy to land the followups.
#if defined(COMPILER_GCC)
#if PA_BUILDFLAG(PA_COMPILER_GCC)
#if defined(ARCH_CPU_X86_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
// TODO(crbug.com/40625592): In theory, it should be possible to use just
// int3. However, there are a number of crashes with SIGILL as the exception
@@ -49,15 +49,15 @@
// to continue after SIGTRAP.
#define PA_TRAP_SEQUENCE1_() asm volatile("int3")
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
// Intentionally empty: __builtin_unreachable() is always part of the sequence
// (see PA_IMMEDIATE_CRASH below) and already emits a ud2 on Mac.
#define PA_TRAP_SEQUENCE2_() asm volatile("")
#else
#define PA_TRAP_SEQUENCE2_() asm volatile("ud2")
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
#elif defined(ARCH_CPU_ARMEL)
#elif PA_BUILDFLAG(PA_ARCH_CPU_ARMEL)
// bkpt will generate a SIGBUS when running on armv7 and a SIGTRAP when running
// as a 32 bit userspace app on arm64. There doesn't seem to be any way to
@@ -67,7 +67,7 @@
#define PA_TRAP_SEQUENCE1_() asm volatile("bkpt #0")
#define PA_TRAP_SEQUENCE2_() asm volatile("udf #0")
#elif defined(ARCH_CPU_ARM64)
#elif PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// This will always generate a SIGTRAP on arm64.
// TODO(crbug.com/40625592): Remove brk from this sequence.
@@ -83,7 +83,7 @@
#endif // ARCH_CPU_*
#elif defined(COMPILER_MSVC)
#elif PA_BUILDFLAG(PA_COMPILER_MSVC)
#if !defined(__clang__)
@@ -91,7 +91,7 @@
#define PA_TRAP_SEQUENCE1_() __debugbreak()
#define PA_TRAP_SEQUENCE2_()
#elif defined(ARCH_CPU_ARM64)
#elif PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// Windows ARM64 uses "BRK #F000" as its breakpoint instruction, and
// __debugbreak() generates that in both VC++ and clang.
@@ -128,7 +128,7 @@
// calling function, but to this anonymous lambda. This is still useful as the
// full name of the lambda will typically include the name of the function that
// calls CHECK() and the debugger will still break at the right line of code.
#if !defined(COMPILER_GCC) || defined(__clang__)
#if !PA_BUILDFLAG(PA_COMPILER_GCC) || defined(__clang__)
#define PA_WRAPPED_TRAP_SEQUENCE_() PA_TRAP_SEQUENCE_()
@@ -139,9 +139,9 @@
[] { PA_TRAP_SEQUENCE_(); }(); \
} while (false)
#endif // !defined(COMPILER_GCC) || defined(__clang__)
#endif // !PA_BUILDFLAG(PA_COMPILER_GCC) || defined(__clang__)
#if defined(__clang__) || defined(COMPILER_GCC)
#if defined(__clang__) || PA_BUILDFLAG(PA_COMPILER_GCC)
// __builtin_unreachable() hints to the compiler that this is noreturn and can
// be packed in the function epilogue.
@@ -158,6 +158,6 @@
// pdfium. On MSVC there is no __builtin_unreachable().
#define PA_IMMEDIATE_CRASH() PA_WRAPPED_TRAP_SEQUENCE_()
#endif // defined(__clang__) || defined(COMPILER_GCC)
#endif // defined(__clang__) || PA_BUILDFLAG(PA_COMPILER_GCC)
#endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_IMMEDIATE_CRASH_H_
@@ -24,13 +24,13 @@
#include "partition_alloc/partition_alloc_base/strings/string_util.h"
#include "partition_alloc/partition_alloc_base/strings/stringprintf.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#include <io.h>
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#include <unistd.h>
#include <cerrno>
@@ -39,7 +39,7 @@
#include <cstring>
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#include "partition_alloc/partition_alloc_base/posix/safe_strerror.h"
#endif
@@ -111,8 +111,9 @@ LogMessage::~LogMessage() {
RawLog(severity_, str_newline);
// TODO(crbug.com/40213558): Enable a stack trace on a fatal on fuchsia.
#if !defined(OFFICIAL_BUILD) && (BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_WIN)) && \
!defined(__UCLIBC__) && !BUILDFLAG(IS_AIX)
#if !defined(OFFICIAL_BUILD) && \
(PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_WIN)) && \
!defined(__UCLIBC__) && !PA_BUILDFLAG(IS_AIX)
// TODO(crbug.com/40213558): Show a stack trace on a fatal, unless a debugger
// is attached.
if (severity_ == LOGGING_FATAL) {
@@ -149,7 +150,7 @@ void LogMessage::Init(const char* file, int line) {
message_start_ = strlen(stream_.c_str());
}
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// This has already been defined in the header, but defining it again as DWORD
// ensures that the type used in the header is equivalent to DWORD. If not,
// the redefinition is a compile error.
@@ -157,9 +158,9 @@ typedef DWORD SystemErrorCode;
#endif
SystemErrorCode GetLastSystemErrorCode() {
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
return ::GetLastError();
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
return errno;
#endif
}
@@ -167,7 +168,7 @@ SystemErrorCode GetLastSystemErrorCode() {
void SystemErrorCodeToStream(base::strings::CStringBuilder& os,
SystemErrorCode error_code) {
char buffer[256];
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
const int kErrorMessageBufferSize = 256;
char msgbuf[kErrorMessageBufferSize];
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
@@ -188,13 +189,13 @@ void SystemErrorCodeToStream(base::strings::CStringBuilder& os,
"Error (0x%x) while retrieving error. (0x%x)",
GetLastError(), error_code);
os << buffer;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
base::safe_strerror_r(error_code, buffer, sizeof(buffer));
os << buffer << " (" << error_code << ")";
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
}
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
int line,
LogSeverity severity,
@@ -209,7 +210,7 @@ Win32ErrorLogMessage::~Win32ErrorLogMessage() {
DWORD last_error = err_;
base::debug::Alias(&last_error);
}
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
ErrnoLogMessage::ErrnoLogMessage(const char* file,
int line,
LogSeverity severity,
@@ -224,6 +225,6 @@ ErrnoLogMessage::~ErrnoLogMessage() {
int last_error = err_;
base::debug::Alias(&last_error);
}
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
} // namespace partition_alloc::internal::logging
@@ -102,9 +102,9 @@ class LogMessageVoidify {
void operator&(base::strings::CStringBuilder&) {}
};
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
typedef unsigned long SystemErrorCode;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
typedef int SystemErrorCode;
#endif
@@ -113,7 +113,7 @@ typedef int SystemErrorCode;
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
SystemErrorCode GetLastSystemErrorCode();
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// Appends a formatted system message of the GetLastError() type.
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Win32ErrorLogMessage
: public LogMessage {
@@ -130,7 +130,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Win32ErrorLogMessage
private:
SystemErrorCode err_;
};
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// Appends a formatted system message of the errno type
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ErrnoLogMessage
: public LogMessage {
@@ -147,7 +147,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ErrnoLogMessage
private:
SystemErrorCode err_;
};
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
} // namespace partition_alloc::internal::logging
@@ -21,13 +21,13 @@
#include "partition_alloc/partition_alloc_base/debug/alias.h"
#include "partition_alloc/partition_alloc_base/immediate_crash.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#include <io.h>
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#include <unistd.h>
#include <cerrno>
@@ -44,7 +44,7 @@ namespace {
int g_min_log_level = 0;
#if !BUILDFLAG(IS_WIN)
#if !PA_BUILDFLAG(IS_WIN)
void WriteToStderr(const char* data, size_t length) {
size_t bytes_written = 0;
int rv;
@@ -58,7 +58,7 @@ void WriteToStderr(const char* data, size_t length) {
bytes_written += rv;
}
}
#else // !BUILDFLAG(IS_WIN)
#else // !PA_BUILDFLAG(IS_WIN)
void WriteToStderr(const char* data, size_t length) {
HANDLE handle = ::GetStdHandle(STD_ERROR_HANDLE);
const char* ptr = data;
@@ -73,7 +73,7 @@ void WriteToStderr(const char* data, size_t length) {
ptr += bytes_written;
}
}
#endif // !BUILDFLAG(IS_WIN)
#endif // !PA_BUILDFLAG(IS_WIN)
} // namespace
@@ -100,11 +100,11 @@ int GetVlogVerbosity() {
void RawLog(int level, const char* message) {
if (level >= g_min_log_level && message) {
#if !BUILDFLAG(IS_WIN)
#if !PA_BUILDFLAG(IS_WIN)
const size_t message_len = strlen(message);
#else // !BUILDFLAG(IS_WIN)
#else // !PA_BUILDFLAG(IS_WIN)
const size_t message_len = ::lstrlenA(message);
#endif // !BUILDFLAG(IS_WIN)
#endif // !PA_BUILDFLAG(IS_WIN)
WriteToStderr(message, message_len);
if (message_len > 0 && message[message_len - 1] != '\n') {
@@ -207,7 +207,7 @@ PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) int GetVlogVerbosity();
#define PA_COMPACT_GOOGLE_LOG_DFATAL PA_COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage)
#define PA_COMPACT_GOOGLE_LOG_DCHECK PA_COMPACT_GOOGLE_LOG_EX_DCHECK(LogMessage)
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// wingdi.h defines ERROR to be 0. When we call PA_LOG(ERROR), it gets
// substituted with 0, and it expands to PA_COMPACT_GOOGLE_LOG_0. To allow us
// to keep using this syntax, we define this macro to do the same thing
@@ -270,13 +270,13 @@ constexpr LogSeverity LOGGING_0 = LOGGING_ERROR;
PA_LAZY_STREAM(PA_VLOG_STREAM(verbose_level), \
PA_VLOG_IS_ON(verbose_level) && (condition))
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#define PA_VPLOG_STREAM(verbose_level) \
::partition_alloc::internal::logging::Win32ErrorLogMessage( \
__FILE__, __LINE__, -(verbose_level), \
::partition_alloc::internal::logging::GetLastSystemErrorCode()) \
.stream()
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#define PA_VPLOG_STREAM(verbose_level) \
::partition_alloc::internal::logging::ErrnoLogMessage( \
__FILE__, __LINE__, -(verbose_level), \
@@ -297,13 +297,13 @@ constexpr LogSeverity LOGGING_0 = LOGGING_ERROR;
PA_LOG_IF(FATAL, !(PA_ANALYZER_ASSUME_TRUE(condition))) \
<< "Assert failed: " #condition ". "
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#define PA_PLOG_STREAM(severity) \
PA_COMPACT_GOOGLE_PLOG_EX_##severity( \
Win32ErrorLogMessage, \
::partition_alloc::internal::logging::GetLastSystemErrorCode()) \
.stream()
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#define PA_PLOG_STREAM(severity) \
PA_COMPACT_GOOGLE_PLOG_EX_##severity( \
ErrnoLogMessage, \
@@ -34,7 +34,7 @@ RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
// these functions out-of-line. However, compilers are wily. Further testing may
// show that `PA_NOINLINE` helps or hurts.
//
#if !defined(ARCH_CPU_X86_FAMILY)
#if !PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
bool RefCountedThreadSafeBase::Release() const {
return ReleaseImpl();
}
@@ -42,7 +42,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) RefCountedThreadSafeBase {
// Release and AddRef are suitable for inlining on X86 because they generate
// very small code sequences. On other platforms (ARM), it causes a size
// regression and is probably not worth it.
#if defined(ARCH_CPU_X86_FAMILY)
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY)
// Returns true if the object should self-delete.
bool Release() const { return ReleaseImpl(); }
void AddRef() const { AddRefImpl(); }
@@ -14,17 +14,17 @@
#include "partition_alloc/partition_alloc_base/component_export.h"
#include "partition_alloc/partition_alloc_base/files/file_path.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#endif // OS_*
namespace partition_alloc::internal::base {
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
using NativeLibrary = HMODULE;
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
enum NativeLibraryType { BUNDLE, DYNAMIC_LIB };
enum NativeLibraryObjCStatus {
OBJC_UNKNOWN,
@@ -41,23 +41,23 @@ struct NativeLibraryStruct {
};
};
using NativeLibrary = NativeLibraryStruct*;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
using NativeLibrary = void*;
#endif // OS_*
struct PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) NativeLibraryLoadError {
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
NativeLibraryLoadError() : code(0) {}
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
// Returns a string representation of the load error.
std::string ToString() const;
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
DWORD code;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
std::string message;
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
};
struct PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) NativeLibraryOptions {
@@ -32,7 +32,7 @@ NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path,
// http://crbug.com/17943, http://crbug.com/17557, http://crbug.com/36892,
// and http://crbug.com/40794.
int flags = RTLD_LAZY;
#if BUILDFLAG(IS_ANDROID) || !defined(RTLD_DEEPBIND)
#if PA_BUILDFLAG(IS_ANDROID) || !defined(RTLD_DEEPBIND)
// Certain platforms don't define RTLD_DEEPBIND. Android dlopen() requires
// further investigation, as it might vary across versions. Crash here to
// warn developers that they're trying to rely on uncertain behavior.
@@ -17,7 +17,7 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/numerics/safe_conversions.h"
#if BUILDFLAG(IS_ASMJS)
#if PA_BUILDFLAG(IS_ASMJS)
// Optimized safe math instructions are incompatible with asmjs.
#define PA_BASE_HAS_OPTIMIZED_SAFE_MATH (0)
// Where available use builtin math overflow support on Clang and GCC.
@@ -19,13 +19,13 @@
#include "partition_alloc/build_config.h"
#if BUILDFLAG(IS_POSIX)
#if PA_BUILDFLAG(IS_POSIX)
#include <cerrno>
#include <utility>
#endif
namespace partition_alloc {
#if BUILDFLAG(IS_POSIX)
#if PA_BUILDFLAG(IS_POSIX)
template <typename Fn>
inline auto WrapEINTR(Fn fn) {
@@ -46,14 +46,14 @@ inline auto WrapEINTR(Fn fn) {
};
}
#else // !BUILDFLAG(IS_POSIX)
#else // !PA_BUILDFLAG(IS_POSIX)
template <typename Fn>
inline auto WrapEINTR(Fn fn) {
return fn;
}
#endif // !BUILDFLAG(IS_POSIX)
#endif // !PA_BUILDFLAG(IS_POSIX)
} // namespace partition_alloc
@@ -12,11 +12,11 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include "partition_alloc/partition_alloc_base/win/windows_types.h"
#endif
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
#include <zircon/types.h>
#endif
@@ -25,17 +25,17 @@ namespace partition_alloc::internal::base {
// ProcessHandle is a platform specific type which represents the underlying OS
// handle to a process.
// ProcessId is a number which identifies the process in the OS.
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
typedef DWORD ProcessId;
const ProcessId kNullProcessId = 0;
#elif BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_FUCHSIA)
typedef zx_koid_t ProcessId;
const ProcessId kNullProcessId = ZX_KOID_INVALID;
#elif BUILDFLAG(IS_POSIX)
#elif PA_BUILDFLAG(IS_POSIX)
// On POSIX, our ProcessHandle will just be the PID.
typedef pid_t ProcessId;
const ProcessId kNullProcessId = 0;
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
// Returns the id of the current process.
// Note that on some platforms, this is not guaranteed to be unique across
@@ -20,7 +20,7 @@
#include "partition_alloc/partition_alloc_base/no_destructor.h"
#include "partition_alloc/partition_alloc_base/posix/eintr_wrapper.h"
#if BUILDFLAG(IS_MAC)
#if PA_BUILDFLAG(IS_MAC)
// TODO(crbug.com/40641285): Waiting for this header to appear in the iOS SDK.
// (See below.)
#include <sys/random.h>
@@ -28,7 +28,7 @@
namespace {
#if BUILDFLAG(IS_AIX)
#if PA_BUILDFLAG(IS_AIX)
// AIX has no 64-bit support for O_CLOEXEC.
static constexpr int kOpenFlags = O_RDONLY;
#else
@@ -79,7 +79,7 @@ namespace partition_alloc::internal::base {
// (https://chromium-review.googlesource.com/c/chromium/src/+/1545096) and land
// it or some form of it.
void RandBytes(void* output, size_t output_length) {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
// Use `syscall(__NR_getrandom...` to avoid a dependency on
// `third_party/linux_syscall_support.h`.
//
@@ -96,7 +96,7 @@ void RandBytes(void* output, size_t output_length) {
PA_MSAN_UNPOISON(output, output_length);
return;
}
#elif BUILDFLAG(IS_MAC)
#elif PA_BUILDFLAG(IS_MAC)
// TODO(crbug.com/40641285): Enable this on iOS too, when sys/random.h arrives
// in its SDK.
if (getentropy(output, output_length) == 0) {
@@ -30,7 +30,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ScopedClearLastErrorBase {
const int last_errno_;
};
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// Windows specific implementation of ScopedClearLastError.
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ScopedClearLastError
@@ -45,11 +45,11 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ScopedClearLastError
const unsigned long last_system_error_;
};
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
using ScopedClearLastError = ScopedClearLastErrorBase;
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
} // namespace partition_alloc::internal::base
@@ -8,7 +8,7 @@
#include "partition_alloc/partition_alloc_base/debug/debugging_buildflags.h"
#include "partition_alloc/partition_alloc_base/strings/safe_sprintf.h"
#if !BUILDFLAG(IS_WIN)
#if !PA_BUILDFLAG(IS_WIN)
#include <unistd.h>
#endif
@@ -10,7 +10,7 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#if !BUILDFLAG(IS_WIN)
#if !PA_BUILDFLAG(IS_WIN)
#include <unistd.h>
#endif
@@ -118,7 +118,7 @@ class Buffer {
// MSVS2013's standard library doesn't mark max() as constexpr yet. cl.exe
// supports static_cast but doesn't really implement constexpr yet so it doesn't
// complain, but clang does.
#if __cplusplus >= 201103 && !(defined(__clang__) && BUILDFLAG(IS_WIN))
#if __cplusplus >= 201103 && !(defined(__clang__) && PA_BUILDFLAG(IS_WIN))
static_assert(kSSizeMaxConst ==
static_cast<size_t>(std::numeric_limits<ssize_t>::max()),
"kSSizeMaxConst should be the max value of an ssize_t");
@@ -11,7 +11,7 @@
#include "partition_alloc/build_config.h"
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// For ssize_t
#include <unistd.h>
#endif
@@ -20,7 +20,7 @@
namespace partition_alloc::internal::base::strings {
#if defined(COMPILER_MSVC)
#if PA_BUILDFLAG(PA_COMPILER_MSVC)
// Define ssize_t inside of our namespace.
#if defined(_WIN64)
typedef int64_t ssize_t;
@@ -18,14 +18,14 @@ std::string PA_PRINTF_FORMAT(1, 2)
char stack_buf[kMaxLengthOfTruncatingStringPrintfResult + 1];
va_list arguments;
va_start(arguments, format);
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
int result = vsnprintf_s(stack_buf, std::size(stack_buf), _TRUNCATE, format,
arguments);
#else
int result = vsnprintf(stack_buf, std::size(stack_buf), format, arguments);
#endif
va_end(arguments);
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// If an output error is encountered or data is larger than count,
// a negative value is returned. So to see whether an output error is really
// encountered or not, need to see errno. If errno == EINVAL or
@@ -17,13 +17,13 @@
#include "partition_alloc/partition_alloc_base/threading/platform_thread_ref.h"
#include "partition_alloc/partition_alloc_base/time/time.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include "partition_alloc/partition_alloc_base/win/windows_types.h"
#elif BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_FUCHSIA)
#include <zircon/types.h>
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
#include <mach/mach_types.h>
#elif BUILDFLAG(IS_POSIX)
#elif PA_BUILDFLAG(IS_POSIX)
#include <pthread.h>
#include <unistd.h>
#endif
@@ -31,22 +31,22 @@
namespace partition_alloc::internal::base {
// Used for logging. Always an integer value.
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
typedef DWORD PlatformThreadId;
#elif BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_FUCHSIA)
typedef zx_handle_t PlatformThreadId;
#elif BUILDFLAG(IS_APPLE)
#elif PA_BUILDFLAG(IS_APPLE)
typedef mach_port_t PlatformThreadId;
#elif BUILDFLAG(IS_POSIX)
#elif PA_BUILDFLAG(IS_POSIX)
typedef pid_t PlatformThreadId;
#endif
// Used to operate on threads.
class PlatformThreadHandle {
public:
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
typedef void* Handle;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
typedef pthread_t Handle;
#endif
@@ -52,7 +52,7 @@ void PlatformThreadForTesting::YieldCurrentThread() {
}
size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
#if BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(IS_IOS)
return 0;
#else
// The macOS default for a pthread stack size is 512kB.
@@ -60,7 +60,7 @@ class PlatformThreadForTesting : public PlatformThread {
// `thread_handle`.
static void Join(PlatformThreadHandle thread_handle);
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// Returns the default thread stack size set by chrome. If we do not
// explicitly set default size then returns 0.
static size_t GetDefaultThreadStackSize();
@@ -10,14 +10,14 @@
namespace partition_alloc::internal::base::internal {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
// Current thread id is cached in thread local storage for performance reasons.
// In some rare cases it's important to invalidate that cache explicitly (e.g.
// after going through clone() syscall which does not call pthread_atfork()
// handlers).
// This can only be called when the process is single-threaded.
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) void InvalidateTidCache();
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#endif // PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
} // namespace partition_alloc::internal::base::internal
@@ -18,18 +18,18 @@
#include "partition_alloc/partition_alloc_base/logging.h"
#include "partition_alloc/partition_alloc_base/threading/platform_thread_internal_posix.h"
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
#include <sys/syscall.h>
#include <atomic>
#endif
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
#include <zircon/process.h>
#endif
namespace partition_alloc::internal::base {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#if PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
namespace {
@@ -72,15 +72,15 @@ void InvalidateTidCache() {
} // namespace internal
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#endif // PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
// static
PlatformThreadId PlatformThread::CurrentId() {
// Pthreads doesn't have the concept of a thread ID, so we have to reach down
// into the kernel.
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
return pthread_mach_thread_np(pthread_self());
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#elif PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS)
static InitAtFork init_at_fork;
if (g_thread_id == -1 ||
(g_is_main_thread &&
@@ -106,20 +106,20 @@ PlatformThreadId PlatformThread::CurrentId() {
#endif
}
return g_thread_id;
#elif BUILDFLAG(IS_ANDROID)
#elif PA_BUILDFLAG(IS_ANDROID)
// Note: do not cache the return value inside a thread_local variable on
// Android (as above). The reasons are:
// - thread_local is slow on Android (goes through emutls)
// - gettid() is fast, since its return value is cached in pthread (in the
// thread control block of pthread). See gettid.c in bionic.
return gettid();
#elif BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_FUCHSIA)
return zx_thread_self();
#elif BUILDFLAG(IS_SOLARIS) || BUILDFLAG(IS_QNX)
#elif PA_BUILDFLAG(IS_SOLARIS) || PA_BUILDFLAG(IS_QNX)
return pthread_self();
#elif BUILDFLAG(IS_POSIX) && BUILDFLAG(IS_AIX)
#elif PA_BUILDFLAG(IS_POSIX) && PA_BUILDFLAG(IS_AIX)
return pthread_self();
#elif BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_AIX)
#elif PA_BUILDFLAG(IS_POSIX) && !PA_BUILDFLAG(IS_AIX)
return reinterpret_cast<int64_t>(pthread_self());
#endif
}
@@ -20,7 +20,7 @@
#include "partition_alloc/partition_alloc_base/threading/platform_thread_internal_posix.h"
#include "partition_alloc/partition_alloc_buildflags.h"
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
#include <zircon/process.h>
#else
#include <sys/resource.h>
@@ -109,12 +109,12 @@ bool CreateThread(size_t stack_size,
} // namespace
#if !BUILDFLAG(IS_APPLE)
#if !PA_BUILDFLAG(IS_APPLE)
// static
void PlatformThreadForTesting::YieldCurrentThread() {
sched_yield();
}
#endif // !BUILDFLAG(IS_APPLE)
#endif // !PA_BUILDFLAG(IS_APPLE)
// static
bool PlatformThreadForTesting::Create(size_t stack_size,
@@ -15,9 +15,9 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include "partition_alloc/partition_alloc_base/win/windows_types.h"
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#include <pthread.h>
#endif
@@ -33,9 +33,9 @@ namespace partition_alloc::internal::base {
// to distinguish a new thread from an old, dead thread.
class PlatformThreadRef {
public:
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
using RefType = DWORD;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
using RefType = pthread_t;
#endif
@@ -90,7 +90,7 @@ bool CreateThreadInternal(size_t stack_size,
unsigned int flags = 0;
if (stack_size > 0) {
flags = STACK_SIZE_PARAM_IS_A_RESERVATION;
#if defined(ARCH_CPU_32_BITS)
#if PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
} else {
// The process stack size is increased to give spaces to |RendererMain| in
// |chrome/BUILD.gn|, but keep the default stack size of other threads to
@@ -165,7 +165,7 @@ double Time::InSecondsFSinceUnixEpoch() const {
: std::numeric_limits<double>::infinity();
}
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// static
Time Time::FromTimeSpec(const timespec& ts) {
return FromSecondsSinceUnixEpoch(ts.tv_sec + static_cast<double>(ts.tv_nsec) /
@@ -68,36 +68,35 @@
#include <limits>
#include "partition_alloc/build_config.h"
#include "partition_alloc/chromeos_buildflags.h"
#include "partition_alloc/partition_alloc_base/check.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#include "partition_alloc/partition_alloc_base/numerics/clamped_math.h"
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
#include "partition_alloc/partition_alloc_buildflags.h"
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
#include <zircon/types.h>
#endif
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#include <mach/mach_time.h>
// Avoid Mac system header macro leak.
#undef TYPE_BOOL
#endif
#if BUILDFLAG(IS_ANDROID)
#if PA_BUILDFLAG(IS_ANDROID)
#include <jni.h>
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
#include <sys/time.h>
#include <unistd.h>
#endif
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
#include "partition_alloc/partition_alloc_base/win/windows_types.h"
namespace ABI {
@@ -116,7 +115,7 @@ class TimeDelta;
template <typename T>
constexpr TimeDelta Microseconds(T n);
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
class PlatformThreadHandle;
#endif
@@ -126,21 +125,21 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) TimeDelta {
public:
constexpr TimeDelta() = default;
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
static TimeDelta FromQPCValue(LONGLONG qpc_value);
// TODO(crbug.com/40638442): Avoid base::TimeDelta factory functions
// based on absolute time
static TimeDelta FromFileTime(FILETIME ft);
static TimeDelta FromWinrtDateTime(ABI::Windows::Foundation::DateTime dt);
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
static TimeDelta FromTimeSpec(const timespec& ts);
#endif
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
static TimeDelta FromZxDuration(zx_duration_t nanos);
#endif
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
static TimeDelta FromMachTime(uint64_t mach_time);
#endif // BUILDFLAG(IS_APPLE)
#endif // PA_BUILDFLAG(IS_APPLE)
// Converts an integer value representing TimeDelta to a class. This is used
// when deserializing a |TimeDelta| structure, using a value known to be
@@ -195,13 +194,13 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) TimeDelta {
constexpr bool is_min() const { return *this == Min(); }
constexpr bool is_inf() const { return is_min() || is_max(); }
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
struct timespec ToTimeSpec() const;
#endif
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
zx_duration_t ToZxDuration() const;
#endif
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
ABI::Windows::Foundation::DateTime ToWinrtDateTime() const;
#endif
@@ -490,8 +489,8 @@ class TimeBase {
int64_t us_;
};
#if BUILDFLAG(IS_WIN)
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// TSCTicksPerSecond is not supported on Windows on Arm systems because the
// cycle-counting methods use the actual CPU cycle count, and not a consistent
// incrementing counter.
@@ -505,7 +504,7 @@ class TimeBase {
[[nodiscard]] PA_COMPONENT_EXPORT(
PARTITION_ALLOC_BASE) double TSCTicksPerSecond();
#endif
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
} // namespace time_internal
@@ -530,7 +529,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Time
static constexpr int64_t kTimeTToMicrosecondsOffset =
INT64_C(11644473600000000);
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// To avoid overflow in QPC to Microseconds calculations, since we multiply
// by kMicrosecondsPerSecond, then the QPC value should not exceed
// (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply.
@@ -590,7 +589,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Time
static Time FromSecondsSinceUnixEpoch(double dt);
double InSecondsFSinceUnixEpoch() const;
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// Converts the timespec structure to time. MacOS X 10.8.3 (and tentatively,
// earlier versions) will have the |ts|'s tv_nsec component zeroed out,
// having a 1 second resolution, which agrees with
@@ -617,17 +616,17 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Time
static Time FromMillisecondsSinceUnixEpoch(int64_t ms_since_epoch);
int64_t InMillisecondsSinceUnixEpoch() const;
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
static Time FromTimeVal(struct timeval t);
struct timeval ToTimeVal() const;
#endif
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
static Time FromZxTime(zx_time_t time);
zx_time_t ToZxTime() const;
#endif
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
static Time FromCFAbsoluteTime(CFAbsoluteTime t);
CFAbsoluteTime ToCFAbsoluteTime() const;
#if defined(__OBJC__)
@@ -636,10 +635,10 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Time
#endif
#endif
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
static Time FromFileTime(FILETIME ft);
FILETIME ToFileTime() const;
#endif // BUILDFLAG(IS_WIN)
#endif // PA_BUILDFLAG(IS_WIN)
// For legacy deserialization only. Converts an integer value representing
// Time to a class. This may be used when deserializing a |Time| structure,
@@ -844,58 +843,27 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) TimeTicks
// considered to have an ambiguous ordering.)
[[nodiscard]] static bool IsConsistentAcrossProcesses();
#if BUILDFLAG(IS_FUCHSIA)
#if PA_BUILDFLAG(IS_FUCHSIA)
// Converts between TimeTicks and an ZX_CLOCK_MONOTONIC zx_time_t value.
static TimeTicks FromZxTime(zx_time_t nanos_since_boot);
zx_time_t ToZxTime() const;
#endif
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// Translates an absolute QPC timestamp into a TimeTicks value. The returned
// value has the same origin as Now(). Do NOT attempt to use this if
// IsHighResolution() returns false.
static TimeTicks FromQPCValue(LONGLONG qpc_value);
#endif
#if BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_APPLE)
static TimeTicks FromMachAbsoluteTime(uint64_t mach_absolute_time);
// Sets the current Mach timebase to `timebase`. Returns the old timebase.
static mach_timebase_info_data_t SetMachTimebaseInfoForTesting(
mach_timebase_info_data_t timebase);
#endif // BUILDFLAG(IS_APPLE)
#if BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(PA_IS_CHROMEOS_ASH)
// Converts to TimeTicks the value obtained from SystemClock.uptimeMillis().
// Note: this conversion may be non-monotonic in relation to previously
// obtained TimeTicks::Now() values because of the truncation (to
// milliseconds) performed by uptimeMillis().
static TimeTicks FromUptimeMillis(int64_t uptime_millis_value);
#endif // BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(PA_IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_ANDROID)
// Converts to TimeTicks the value obtained from System.nanoTime(). This
// conversion will be monotonic in relation to previously obtained
// TimeTicks::Now() values as the clocks are based on the same posix monotonic
// clock, with nanoTime() potentially providing higher resolution.
static TimeTicks FromJavaNanoTime(int64_t nano_time_value);
// Truncates the TimeTicks value to the precision of SystemClock#uptimeMillis.
// Note that the clocks already share the same monotonic clock source.
jlong ToUptimeMillis() const;
// Returns the TimeTicks value as microseconds in the timebase of
// SystemClock#uptimeMillis.
// Note that the clocks already share the same monotonic clock source.
//
// System.nanoTime() may be used to get sub-millisecond precision in Java code
// and may be compared against this value as the two share the same clock
// source (though be sure to convert nanos to micros).
jlong ToUptimeMicros() const;
#endif // BUILDFLAG(IS_ANDROID)
#endif // PA_BUILDFLAG(IS_APPLE)
// Get an estimate of the TimeTick value at the time of the UnixEpoch. Because
// Time and TimeTicks respond differently to user-set time and NTP
@@ -932,7 +900,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) TimeTicks
}
protected:
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
typedef DWORD (*TickFunctionType)(void);
static TickFunctionType SetMockTickFunction(TickFunctionType ticker);
#endif
@@ -957,9 +925,10 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ThreadTicks
// Returns true if ThreadTicks::Now() is supported on this system.
[[nodiscard]] static bool IsSupported() {
#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
PA_BUILDFLAG(IS_APPLE) || PA_BUILDFLAG(IS_ANDROID) || \
PA_BUILDFLAG(IS_FUCHSIA)
return true;
#elif BUILDFLAG(IS_WIN)
#elif PA_BUILDFLAG(IS_WIN)
return IsSupportedWin();
#else
return false;
@@ -969,7 +938,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ThreadTicks
// Waits until the initialization is completed. Needs to be guarded with a
// call to IsSupported().
static void WaitUntilInitialized() {
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
WaitUntilInitializedWin();
#endif
}
@@ -983,7 +952,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ThreadTicks
// absolutely needed, call WaitUntilInitialized() before this method.
static ThreadTicks Now();
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
// Similar to Now() above except this returns thread-specific CPU time for an
// arbitrary thread. All comments for Now() method above apply apply to this
// method as well.
@@ -1010,7 +979,7 @@ class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ThreadTicks
// internal use and testing.
constexpr explicit ThreadTicks(int64_t us) : TimeBase(us) {}
#if BUILDFLAG(IS_WIN)
#if PA_BUILDFLAG(IS_WIN)
[[nodiscard]] static bool IsSupportedWin();
static void WaitUntilInitializedWin();
#endif
@@ -1,65 +0,0 @@
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "partition_alloc/partition_alloc_base/time/time.h"
namespace partition_alloc::internal::base {
// static
TimeTicks TimeTicks::FromUptimeMillis(int64_t uptime_millis_value) {
// The implementation of the SystemClock.uptimeMillis() in AOSP uses the same
// clock as base::TimeTicks::Now(): clock_gettime(CLOCK_MONOTONIC), see in
// platform/system/code:
// 1. libutils/SystemClock.cpp
// 2. libutils/Timers.cpp
//
// We are not aware of any motivations for Android OEMs to modify the AOSP
// implementation of either uptimeMillis() or clock_gettime(CLOCK_MONOTONIC),
// so we assume that there are no such customizations.
//
// Under these assumptions the conversion is as safe as copying the value of
// base::TimeTicks::Now() with a loss of sub-millisecond precision.
return TimeTicks(uptime_millis_value * Time::kMicrosecondsPerMillisecond);
}
// This file is included on chromeos_ash because it needs to interpret
// UptimeMillis values from the Android container.
#if BUILDFLAG(IS_ANDROID)
// static
TimeTicks TimeTicks::FromJavaNanoTime(int64_t nano_time_value) {
// The implementation of the System.nanoTime() in AOSP uses the same
// clock as UptimeMillis() and base::TimeTicks::Now():
// clock_gettime(CLOCK_MONOTONIC), see ojluni/src/main/native/System.c in
// AOSP.
//
// From Android documentation on android.os.SystemClock:
// [uptimeMillis()] is the basis for most interval timing such as
// Thread.sleep(millls), Object.wait(millis), and System.nanoTime().
//
// We are not aware of any motivations for Android OEMs to modify the AOSP
// implementation of either uptimeMillis(), nanoTime, or
// clock_gettime(CLOCK_MONOTONIC), so we assume that there are no such
// customizations.
//
// Under these assumptions the conversion is as safe as copying the value of
// base::TimeTicks::Now() without the (theoretical) sub-microsecond
// resolution.
return TimeTicks(nano_time_value / Time::kNanosecondsPerMicrosecond);
}
jlong TimeTicks::ToUptimeMillis() const {
// See FromUptimeMillis. UptimeMillis and TimeTicks use the same clock source,
// and only differ in resolution.
return us_ / Time::kMicrosecondsPerMillisecond;
}
jlong TimeTicks::ToUptimeMicros() const {
// Same as ToUptimeMillis but maintains sub-millisecond precision.
return us_;
}
#endif // BUILDFLAG(IS_ANDROID)
} // namespace partition_alloc::internal::base
@@ -15,7 +15,7 @@
#include <cstdint>
#include <ctime>
#if BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(IS_IOS)
#include <cerrno>
#endif
@@ -9,7 +9,7 @@
#include "partition_alloc/build_config.h"
#include "partition_alloc/partition_alloc_base/time/time.h"
#if BUILDFLAG(IS_ANDROID) && !defined(__LP64__)
#if PA_BUILDFLAG(IS_ANDROID) && !defined(__LP64__)
#include <time64.h>
#endif
#include <unistd.h>
@@ -21,7 +21,7 @@
// Ensure the Fuchsia and Mac builds do not include this module. Instead,
// non-POSIX implementation is used for sampling the system clocks.
#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_APPLE)
#if PA_BUILDFLAG(IS_FUCHSIA) || PA_BUILDFLAG(IS_APPLE)
#error "This implementation is for POSIX platforms other than Fuchsia or Mac."
#endif
@@ -48,9 +48,9 @@ int64_t ConvertTimespecToMicros(const struct timespec& ts) {
// microsecond timebase. Minimum requirement is MONOTONIC_CLOCK to be supported
// on the system. FreeBSD 6 has CLOCK_MONOTONIC but defines
// _POSIX_MONOTONIC_CLOCK to -1.
#if (BUILDFLAG(IS_POSIX) && defined(_POSIX_MONOTONIC_CLOCK) && \
_POSIX_MONOTONIC_CLOCK >= 0) || \
BUILDFLAG(IS_BSD) || BUILDFLAG(IS_ANDROID)
#if (PA_BUILDFLAG(IS_POSIX) && defined(_POSIX_MONOTONIC_CLOCK) && \
_POSIX_MONOTONIC_CLOCK >= 0) || \
PA_BUILDFLAG(IS_BSD) || PA_BUILDFLAG(IS_ANDROID)
int64_t ClockNow(clockid_t clk_id) {
struct timespec ts;
PA_BASE_CHECK(clock_gettime(clk_id, &ts) == 0);
@@ -111,7 +111,7 @@ bool TimeTicks::IsConsistentAcrossProcesses() {
namespace subtle {
ThreadTicks ThreadTicksNowIgnoringOverride() {
#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
BUILDFLAG(IS_ANDROID)
PA_BUILDFLAG(IS_ANDROID)
return ThreadTicks() + Microseconds(ClockNow(CLOCK_THREAD_CPUTIME_ID));
#else
PA_NOTREACHED();
@@ -410,7 +410,7 @@ ThreadTicks ThreadTicks::GetForThread(
const PlatformThreadHandle& thread_handle) {
PA_BASE_DCHECK(IsSupported());
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// QueryThreadCycleTime versus TSCTicksPerSecond doesn't have much relation to
// actual elapsed time on Windows on Arm, because QueryThreadCycleTime is
// backed by the actual number of CPU cycles executed, rather than a
@@ -444,7 +444,7 @@ ThreadTicks ThreadTicks::GetForThread(
// static
bool ThreadTicks::IsSupportedWin() {
#if defined(ARCH_CPU_ARM64)
#if PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
// The Arm implementation does not use QueryThreadCycleTime and therefore does
// not care about the time stamp counter.
return true;
@@ -455,7 +455,7 @@ bool ThreadTicks::IsSupportedWin() {
// static
void ThreadTicks::WaitUntilInitializedWin() {
#if !defined(ARCH_CPU_ARM64)
#if !PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
while (time_internal::TSCTicksPerSecond() == 0) {
::Sleep(10);
}
@@ -491,7 +491,7 @@ ABI::Windows::Foundation::DateTime TimeDelta::ToWinrtDateTime() const {
return date_time;
}
#if !defined(ARCH_CPU_ARM64)
#if !PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
namespace time_internal {
bool HasConstantRateTSC() {
@@ -560,6 +560,6 @@ double TSCTicksPerSecond() {
}
} // namespace time_internal
#endif // defined(ARCH_CPU_ARM64)
#endif // PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
} // namespace partition_alloc::internal::base
@@ -99,8 +99,8 @@
// alignas(16) DebugKv causes breakpad_unittests and sandbox_linux_unittests
// failures on android-marshmallow-x86-rel because of SIGSEGV.
#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_X86_FAMILY) && \
defined(ARCH_CPU_32_BITS)
#if PA_BUILDFLAG(IS_ANDROID) && PA_BUILDFLAG(PA_ARCH_CPU_X86_FAMILY) && \
PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
#define PA_DEBUGKV_ALIGN alignas(8)
#else
#define PA_DEBUGKV_ALIGN alignas(16)
@@ -43,7 +43,7 @@ static_assert(sizeof(void*) != 8, "");
#define PA_CONFIG_STARSCAN_NEON_SUPPORTED() 0
#endif
#if PA_BUILDFLAG(HAS_64_BIT_POINTERS) && BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(HAS_64_BIT_POINTERS) && PA_BUILDFLAG(IS_IOS)
// Allow PA to select an alternate pool size at run-time before initialization,
// rather than using a single constexpr value.
//
@@ -54,10 +54,10 @@ static_assert(sizeof(void*) != 8, "");
#define PA_CONFIG_DYNAMICALLY_SELECT_POOL_SIZE() 1
#else
#define PA_CONFIG_DYNAMICALLY_SELECT_POOL_SIZE() 0
#endif // PA_BUILDFLAG(HAS_64_BIT_POINTERS) && BUILDFLAG(IS_IOS)
#endif // PA_BUILDFLAG(HAS_64_BIT_POINTERS) && PA_BUILDFLAG(IS_IOS)
#if PA_BUILDFLAG(HAS_64_BIT_POINTERS) && \
(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
(PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_ANDROID))
#include <linux/version.h>
// TODO(bikineev): Enable for ChromeOS.
#define PA_CONFIG_STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED() \
@@ -65,7 +65,7 @@ static_assert(sizeof(void*) != 8, "");
#else
#define PA_CONFIG_STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED() 0
#endif // PA_BUILDFLAG(HAS_64_BIT_POINTERS) &&
// (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID))
// (PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_ANDROID))
#if PA_BUILDFLAG(USE_STARSCAN)
// Use card table to avoid races for PCScan configuration without safepoints.
@@ -95,8 +95,9 @@ static_assert(sizeof(void*) != 8, "");
// POSIX is not only UNIX, e.g. macOS and other OSes. We do use Linux-specific
// features such as futex(2).
#define PA_CONFIG_HAS_LINUX_KERNEL() \
(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID))
#define PA_CONFIG_HAS_LINUX_KERNEL() \
(PA_BUILDFLAG(IS_LINUX) || PA_BUILDFLAG(IS_CHROMEOS) || \
PA_BUILDFLAG(IS_ANDROID))
// On some platforms, we implement locking by spinning in userspace, then going
// into the kernel only if there is contention. This requires platform support,
@@ -113,8 +114,9 @@ static_assert(sizeof(void*) != 8, "");
// is available.
//
// Otherwise, a userspace spinlock implementation is used.
#if PA_CONFIG(HAS_LINUX_KERNEL) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || \
BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if PA_CONFIG(HAS_LINUX_KERNEL) || PA_BUILDFLAG(IS_WIN) || \
PA_BUILDFLAG(IS_APPLE) || PA_BUILDFLAG(IS_POSIX) || \
PA_BUILDFLAG(IS_FUCHSIA)
#define PA_CONFIG_HAS_FAST_MUTEX() 1
#else
#define PA_CONFIG_HAS_FAST_MUTEX() 0
@@ -128,7 +130,7 @@ static_assert(sizeof(void*) != 8, "");
// Need TLS support.
#define PA_CONFIG_THREAD_CACHE_SUPPORTED() \
(BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA))
(PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_WIN) || PA_BUILDFLAG(IS_FUCHSIA))
// Too expensive for official builds, as it adds cache misses to all
// allocations. On the other hand, we want wide metrics coverage to get
@@ -150,7 +152,7 @@ static_assert(sizeof(void*) != 8, "");
// 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 defined(ARCH_CPU_LITTLE_ENDIAN)
#if PA_BUILDFLAG(PA_ARCH_CPU_LITTLE_ENDIAN)
#define PA_CONFIG_HAS_FREELIST_SHADOW_ENTRY() 1
#else
#define PA_CONFIG_HAS_FREELIST_SHADOW_ENTRY() 0
@@ -190,8 +192,9 @@ static_assert(sizeof(void*) == 8);
//
// 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) && !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS)
#if !(PA_BUILDFLAG(IS_WIN) && defined(COMPONENT_BUILD)) && \
!PA_BUILDFLAG(IS_APPLE) && !PA_BUILDFLAG(IS_LINUX) && \
!PA_BUILDFLAG(IS_CHROMEOS)
#define PA_CONFIG_THREAD_LOCAL_TLS() 1
#else
#define PA_CONFIG_THREAD_LOCAL_TLS() 0
@@ -206,7 +209,7 @@ static_assert(sizeof(void*) == 8);
// - Not on Android due to bot failures
#if PA_BUILDFLAG(PA_DCHECK_IS_ON) && \
PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \
PA_CONFIG(THREAD_LOCAL_TLS) && !BUILDFLAG(IS_ANDROID)
PA_CONFIG(THREAD_LOCAL_TLS) && !PA_BUILDFLAG(IS_ANDROID)
#define PA_CONFIG_HAS_ALLOCATION_GUARD() 1
#else
#define PA_CONFIG_HAS_ALLOCATION_GUARD() 0
@@ -214,7 +217,7 @@ static_assert(sizeof(void*) == 8);
// On Android, we have to go through emutls, since this is always a shared
// library, so don't bother.
#if PA_CONFIG(THREAD_LOCAL_TLS) && !BUILDFLAG(IS_ANDROID)
#if PA_CONFIG(THREAD_LOCAL_TLS) && !PA_BUILDFLAG(IS_ANDROID)
#define PA_CONFIG_THREAD_CACHE_FAST_TLS() 1
#else
#define PA_CONFIG_THREAD_CACHE_FAST_TLS() 0
@@ -223,7 +226,7 @@ static_assert(sizeof(void*) == 8);
// 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)
#if PA_BUILDFLAG(IS_WIN)
constexpr bool kUseLazyCommit = true;
#else
constexpr bool kUseLazyCommit = false;
@@ -231,8 +234,9 @@ constexpr bool kUseLazyCommit = false;
// On these platforms, lock all the partitions before fork(), and unlock after.
// This may be required on more platforms in the future.
#define PA_CONFIG_HAS_ATFORK_HANDLER() \
(BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
#define PA_CONFIG_HAS_ATFORK_HANDLER() \
(PA_BUILDFLAG(IS_APPLE) || PA_BUILDFLAG(IS_LINUX) || \
PA_BUILDFLAG(IS_CHROMEOS))
// PartitionAlloc uses PartitionRootEnumerator to acquire all
// PartitionRoots at BeforeFork and to release at AfterFork.
@@ -279,7 +283,8 @@ constexpr bool kUseLazyCommit = false;
//
// Also enabled on ARM64 macOS and iOS, as the 16kiB pages on this platform lead
// to larger slot spans.
#if BUILDFLAG(IS_LINUX) || (BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64))
#if PA_BUILDFLAG(IS_LINUX) || \
(PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_ARM64))
#define PA_CONFIG_PREFER_SMALLER_SLOT_SPANS() 1
#else
#define PA_CONFIG_PREFER_SMALLER_SLOT_SPANS() 0
@@ -309,7 +314,7 @@ constexpr bool kUseLazyCommit = false;
//
// The settings has MAYBE_ in the name, because the final decision to enable is
// based on the operarting system version check done at run-time.
#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) && BUILDFLAG(IS_MAC)
#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) && PA_BUILDFLAG(IS_MAC)
#define PA_CONFIG_MAYBE_ENABLE_MAC11_MALLOC_SIZE_HACK() 1
#else
#define PA_CONFIG_MAYBE_ENABLE_MAC11_MALLOC_SIZE_HACK() 0
@@ -330,7 +335,7 @@ constexpr bool kUseLazyCommit = false;
// PA_CONFIG(IS_NONCLANG_MSVC): mimics the compound condition used by
// Chromium's `//base/compiler_specific.h` to detect true (non-Clang)
// MSVC.
#if defined(COMPILER_MSVC) && !defined(__clang__)
#if PA_BUILDFLAG(PA_COMPILER_MSVC) && !defined(__clang__)
#define PA_CONFIG_IS_NONCLANG_MSVC() 1
#else
#define PA_CONFIG_IS_NONCLANG_MSVC() 0
@@ -342,4 +347,8 @@ static_assert(__cplusplus >= 202002L,
"PartitionAlloc targets C++20 or higher.");
#endif // PA_BUILDFLAG(ASSERT_CPP_20)
// Named pass-through that determines whether or not PA should generally
// enforce that `SlotStart` instances are in fact slot starts.
#define PA_CONFIG_ENFORCE_SLOT_STARTS() PA_BUILDFLAG(PA_DCHECK_IS_ON)
#endif // PARTITION_ALLOC_PARTITION_ALLOC_CONFIG_H_
@@ -19,7 +19,7 @@
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/partition_alloc_forward.h"
#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS)
#if PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
#include <mach/vm_page_size.h>
#endif
@@ -100,17 +100,17 @@ constexpr size_t kPartitionCachelineSize = 64;
// other constant values, we pack _all_ `PartitionRoot::Alloc` sizes perfectly
// up against the end of a system page.
#if defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_LOONGARCH64)
#if defined(_MIPS_ARCH_LOONGSON) || PA_BUILDFLAG(PA_ARCH_CPU_LOONGARCH64)
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
PartitionPageShift() {
return 16; // 64 KiB
}
#elif defined(ARCH_CPU_PPC64)
#elif PA_BUILDFLAG(PA_ARCH_CPU_PPC64)
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
PartitionPageShift() {
return 18; // 256 KiB
}
#elif (BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS)) || \
#elif (PA_BUILDFLAG(IS_APPLE) && PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)) || \
defined(PARTITION_ALLOCATOR_CONSTANTS_POSIX_NONCONST_PAGE_SIZE)
PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
PartitionPageShift() {
@@ -303,6 +303,19 @@ enum pool_handle : unsigned {
// kNullPoolHandle doesn't have metadata, hence - 1
constexpr size_t kNumPools = kMaxPoolHandle - 1;
enum class PoolHandleMask {
kNone = 0u,
kRegular = 1u << (kRegularPoolHandle - 1),
kBRP = 1u << (kBRPPoolHandle - 1),
#if PA_BUILDFLAG(HAS_64_BIT_POINTERS)
kConfigurable = 1u << (kConfigurablePoolHandle - 1),
kMaxValue = kConfigurable
#else
kMaxValue = kBRP
#endif
};
PA_DEFINE_OPERATORS_FOR_FLAGS(PoolHandleMask);
// Maximum pool size. With exception of Configurable Pool, it is also
// the actual size, unless PA_DYNAMICALLY_SELECT_POOL_SIZE is set, which
// allows to choose a different size at initialization time for certain
@@ -315,7 +328,7 @@ constexpr size_t kNumPools = kMaxPoolHandle - 1;
// When pointer compression is enabled, we cannot use large pools (at most
// 8GB for each of the glued pools).
#if PA_BUILDFLAG(HAS_64_BIT_POINTERS)
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) || \
#if PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(IS_IOS) || \
PA_BUILDFLAG(ENABLE_POINTER_COMPRESSION)
constexpr size_t kPoolMaxSize = 8 * kGiB;
#else
@@ -513,6 +526,17 @@ constexpr size_t kMac11MallocSizeHackRequestedSize = 32;
} // namespace internal
// When trying to conserve memory, set the thread cache limit to this.
static inline constexpr size_t kThreadCacheDefaultSizeThreshold = 512;
// 32kiB is chosen here as from local experiments, "zone" allocation in
// V8 is performance-sensitive, and zones can (and do) grow up to 32kiB for
// each individual allocation.
static inline constexpr size_t kThreadCacheLargeSizeThreshold = 1 << 15;
static_assert(kThreadCacheLargeSizeThreshold <=
std::numeric_limits<uint16_t>::max(),
"");
// These constants are used outside PartitionAlloc itself, so we provide
// non-internal aliases here.
using ::partition_alloc::internal::kInvalidBucketSize;
@@ -46,17 +46,6 @@ namespace partition_alloc::internal {
namespace {
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
PA_ALWAYS_INLINE uintptr_t ShadowMetadataStart(uintptr_t super_page,
pool_handle pool) {
uintptr_t shadow_metadata_start =
super_page + SystemPageSize() + ShadowPoolOffset(pool);
PA_DCHECK(!PartitionAddressSpace::IsInRegularPool(shadow_metadata_start));
PA_DCHECK(!PartitionAddressSpace::IsInBRPPool(shadow_metadata_start));
return shadow_metadata_start;
}
#endif
[[noreturn]] PA_NOINLINE void PartitionOutOfMemoryMappingFailure(
PartitionRoot* root,
size_t size) PA_LOCKS_EXCLUDED(PartitionRootLock(root)) {
@@ -300,21 +289,27 @@ SlotSpanMetadata* PartitionDirectMap(PartitionRoot* root,
{
ScopedSyscallTimer timer{root};
RecommitSystemPages(reservation_start + SystemPageSize(),
SystemPageSize(),
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kRead),
#else
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kReadWrite),
#endif
PageAccessibilityDisposition::kRequireUpdate);
if (PartitionAddressSpace::IsShadowMetadataEnabled(root->ChoosePool())) {
PartitionAddressSpace::MapMetadata(reservation_start,
/*copy_metadata=*/false);
} else
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
{
RecommitSystemPages(reservation_start + SystemPageSize(),
SystemPageSize(),
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kReadWrite),
PageAccessibilityDisposition::kRequireUpdate);
}
}
if (pool == kBRPPoolHandle) {
// Allocate a system page for BRP ref-count table (only one of its
// elements will be used).
// Allocate a system page for InSlotMetadata table (only one of its
// elements will be used). Shadow metadata does not need to protect
// this table, because (1) corrupting the table won't help with the
// pool escape and (2) accessing the table is on the BRP hot path.
// The protection will cause significant performance regression.
ScopedSyscallTimer timer{root};
RecommitSystemPages(reservation_start + SystemPageSize() * 2,
SystemPageSize(),
@@ -323,17 +318,6 @@ SlotSpanMetadata* PartitionDirectMap(PartitionRoot* root,
PageAccessibilityDisposition::kRequireUpdate);
}
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
{
ScopedSyscallTimer timer{root};
RecommitSystemPages(ShadowMetadataStart(reservation_start, pool),
SystemPageSize(),
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kReadWrite),
PageAccessibilityDisposition::kRequireUpdate);
}
#endif
// No need to hold root->lock_. Now that memory is reserved, no other
// overlapping region can be allocated (because of how pools work),
// so no other thread can update the same offset table entries at the
@@ -405,7 +389,9 @@ SlotSpanMetadata* PartitionDirectMap(PartitionRoot* root,
PA_DCHECK(!direct_map_metadata->bucket.decommitted_slot_spans_head);
PA_DCHECK(!direct_map_metadata->bucket.num_system_pages_per_slot_span);
PA_DCHECK(!direct_map_metadata->bucket.num_full_slot_spans);
direct_map_metadata->bucket.slot_size = slot_size;
direct_map_metadata->bucket.can_store_raw_size = true;
new (&page_metadata->slot_span_metadata)
SlotSpanMetadata(&direct_map_metadata->bucket);
@@ -603,7 +589,8 @@ uint8_t ComputeSystemPagesPerSlotSpan(size_t slot_size,
return ComputeSystemPagesPerSlotSpanInternal(slot_size);
}
void PartitionBucket::Init(uint32_t new_slot_size) {
void PartitionBucket::Init(uint32_t new_slot_size,
bool use_small_single_slot_spans) {
slot_size = new_slot_size;
slot_size_reciprocal = kReciprocalMask / new_slot_size + 1;
active_slot_spans_head = SlotSpanMetadata::get_sentinel_slot_span_non_const();
@@ -619,6 +606,8 @@ void PartitionBucket::Init(uint32_t new_slot_size) {
;
num_system_pages_per_slot_span =
ComputeSystemPagesPerSlotSpan(slot_size, prefer_smaller_slot_spans);
InitCanStoreRawSize(use_small_single_slot_spans);
}
PA_ALWAYS_INLINE SlotSpanMetadata* PartitionBucket::AllocNewSlotSpan(
@@ -698,6 +687,51 @@ PA_ALWAYS_INLINE SlotSpanMetadata* PartitionBucket::AllocNewSlotSpan(
return slot_span;
}
void PartitionBucket::InitCanStoreRawSize(bool use_small_single_slot_spans) {
// By definition, direct map buckets can store the raw size. The value
// of `can_store_raw_size` is set explicitly in that code path (see
// `PartitionDirectMap()`), bypassing this method.
PA_DCHECK(!is_direct_mapped());
can_store_raw_size = false;
// For direct-map as well as single-slot slot spans (recognized by checking
// against |MaxRegularSlotSpanSize()|), we have some spare metadata space in
// subsequent PartitionPage to store the raw size. It isn't only metadata
// space though, slot spans that have more than one slot can't have raw size
// stored, because we wouldn't know which slot it applies to.
if (PA_LIKELY(slot_size <= MaxRegularSlotSpanSize())) {
// Even when the slot size is below the standard floor for single
// slot spans, there exist spans that happen to have exactly one
// slot per. If `use_small_single_slot_spans` is true, we use more
// nuanced criteria for determining if a span is "single-slot."
//
// The conditions are all of:
// * Don't deal with slots trafficked by the thread cache [1].
// * There must be exactly one slot in this span.
// * There must be enough room in the super page metadata area [2]
// to store the raw size - hence, this span must take up more
// than one partition page.
//
// [1] Updating the raw size is considered slow relative to the
// thread cache's fast paths. Letting the thread cache handle
// single-slot spans forces us to stick branches and raw size
// updates into fast paths. We avoid this by holding single-slot
// spans and thread-cache-eligible spans disjoint.
// [2] ../../PartitionAlloc.md#layout-in-memory
const bool not_handled_by_thread_cache =
slot_size > kThreadCacheLargeSizeThreshold;
can_store_raw_size =
use_small_single_slot_spans && not_handled_by_thread_cache &&
get_slots_per_span() == 1u && get_pages_per_slot_span() > 1u;
return;
}
PA_CHECK((slot_size % SystemPageSize()) == 0);
PA_CHECK(get_slots_per_span() == 1);
can_store_raw_size = true;
}
uintptr_t PartitionBucket::AllocNewSuperPageSpan(PartitionRoot* root,
size_t super_page_count,
AllocFlags flags) {
@@ -782,19 +816,25 @@ PartitionBucket::InitializeSuperPage(PartitionRoot* root,
// also a tiny amount of extent metadata.
{
ScopedSyscallTimer timer{root};
RecommitSystemPages(super_page + SystemPageSize(), SystemPageSize(),
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kRead),
#else
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kReadWrite),
#endif
PageAccessibilityDisposition::kRequireUpdate);
if (PartitionAddressSpace::IsShadowMetadataEnabled(root->ChoosePool())) {
PartitionAddressSpace::MapMetadata(super_page, /*copy_metadata=*/false);
} else
#endif // PA_CONFIG(ENABLE_SHADOW_METADATA)
{
RecommitSystemPages(super_page + SystemPageSize(), SystemPageSize(),
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kReadWrite),
PageAccessibilityDisposition::kRequireUpdate);
}
}
if (root->ChoosePool() == kBRPPoolHandle) {
// Allocate a system page for BRP ref-count table.
// Allocate a system page for InSlotMetadata table (only one of its
// elements will be used). Shadow metadata does not need to protect
// this table, because (1) corrupting the table won't help with the
// pool escape and (2) accessing the table is on the BRP hot path.
// The protection will cause significant performance regression.
ScopedSyscallTimer timer{root};
RecommitSystemPages(super_page + SystemPageSize() * 2, SystemPageSize(),
root->PageAccessibilityWithThreadIsolationIfEnabled(
@@ -802,17 +842,6 @@ PartitionBucket::InitializeSuperPage(PartitionRoot* root,
PageAccessibilityDisposition::kRequireUpdate);
}
#if PA_CONFIG(ENABLE_SHADOW_METADATA)
{
ScopedSyscallTimer timer{root};
RecommitSystemPages(ShadowMetadataStart(super_page, root->ChoosePool()),
SystemPageSize(),
root->PageAccessibilityWithThreadIsolationIfEnabled(
PageAccessibilityConfiguration::kReadWrite),
PageAccessibilityDisposition::kRequireUpdate);
}
#endif
// If we were after a specific address, but didn't get it, assume that
// the system chose a lousy address. Here most OS'es have a default
// algorithm that isn't randomized. For example, most Linux
@@ -47,6 +47,7 @@ struct PartitionBucket {
// integer division (or modulo) operation with a pair of multiplication and a
// bit shift, i.e. `value / size` becomes `(value * size_reciprocal) >> M`.
uint64_t slot_size_reciprocal;
bool can_store_raw_size;
// This is `M` from the formula above. For accurate results, both `value` and
// `size`, which are bound by `kMaxBucketed` for our purposes, must be less
@@ -62,7 +63,8 @@ struct PartitionBucket {
static constexpr size_t kMaxSlotSpansToSort = 200;
// Public API.
PA_COMPONENT_EXPORT(PARTITION_ALLOC) void Init(uint32_t new_slot_size);
PA_COMPONENT_EXPORT(PARTITION_ALLOC)
void Init(uint32_t new_slot_size, bool use_small_single_slot_spans);
// Sets |is_already_zeroed| to true if the allocation was satisfied by
// requesting (a) new page(s) from the operating system, or false otherwise.
@@ -81,21 +83,7 @@ struct PartitionBucket {
bool* is_already_zeroed)
PA_EXCLUSIVE_LOCKS_REQUIRED(PartitionRootLock(root));
PA_ALWAYS_INLINE bool CanStoreRawSize() const {
// For direct-map as well as single-slot slot spans (recognized by checking
// against |MaxRegularSlotSpanSize()|), we have some spare metadata space in
// subsequent PartitionPage to store the raw size. It isn't only metadata
// space though, slot spans that have more than one slot can't have raw size
// stored, because we wouldn't know which slot it applies to.
if (PA_LIKELY(slot_size <= MaxRegularSlotSpanSize())) {
return false;
}
PA_DCHECK((slot_size % SystemPageSize()) == 0);
PA_DCHECK(is_direct_mapped() || get_slots_per_span() == 1);
return true;
}
PA_ALWAYS_INLINE bool CanStoreRawSize() const { return can_store_raw_size; }
// Some buckets are pseudo-buckets, which are disabled because they would
// otherwise not fulfill alignment constraints.
@@ -172,6 +160,9 @@ struct PartitionBucket {
void InitializeSlotSpanForGwpAsan(SlotSpanMetadata* slot_span);
private:
// Sets `this->can_store_raw_size`.
void InitCanStoreRawSize(bool use_small_single_slot_spans);
// Allocates several consecutive super pages. Returns the address of the first
// super page.
PA_ALWAYS_INLINE uintptr_t AllocNewSuperPageSpan(PartitionRoot* root,
@@ -10,7 +10,6 @@
#include "partition_alloc/partition_alloc_base/bits.h"
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#include "partition_alloc/partition_alloc_base/no_destructor.h"
#include "partition_alloc/partition_alloc_buildflags.h"
#include "partition_alloc/partition_alloc_constants.h"
@@ -104,8 +103,6 @@ struct PartitionFreelistDispatcher {
PartitionFreelistEntry* entry) const = 0;
PA_ALWAYS_INLINE virtual constexpr bool IsEncodedNextPtrZero(
PartitionFreelistEntry* entry) const = 0;
virtual ~PartitionFreelistDispatcher() = default;
#else
static const PartitionFreelistDispatcher* Create(
PartitionFreelistEncoding encoding) {
@@ -191,7 +188,7 @@ struct PartitionFreelistDispatcher {
#if PA_BUILDFLAG(USE_FREELIST_DISPATCHER)
template <PartitionFreelistEncoding encoding>
struct PartitionFreelistDispatcherImpl : PartitionFreelistDispatcher {
struct PartitionFreelistDispatcherImpl final : PartitionFreelistDispatcher {
using Entry =
std::conditional_t<encoding ==
PartitionFreelistEncoding::kEncodedFreeList,
@@ -295,24 +292,32 @@ struct PartitionFreelistDispatcherImpl : PartitionFreelistDispatcher {
}
};
// Both dispatchers are constexpr
// 1. to avoid "declaration requires an exit-time destructor" error
// e.g. on android-cronet-mainline-clang-arm64-dbg.
// 2. to not create re-entrancy issues with Windows CRT
// (crbug.com/336007395).
inline static constexpr PartitionFreelistDispatcherImpl<
PartitionFreelistEncoding::kEncodedFreeList>
kEncodedImplDispatcher{};
inline static constexpr PartitionFreelistDispatcherImpl<
PartitionFreelistEncoding::kPoolOffsetFreeList>
kPoolOffsetImplDispatcher{};
PA_ALWAYS_INLINE const PartitionFreelistDispatcher*
PartitionFreelistDispatcher::Create(PartitionFreelistEncoding encoding) {
switch (encoding) {
case PartitionFreelistEncoding::kEncodedFreeList: {
static base::NoDestructor<PartitionFreelistDispatcherImpl<
PartitionFreelistEncoding::kEncodedFreeList>>
encoded_impl;
return encoded_impl.get();
return &kEncodedImplDispatcher;
}
case PartitionFreelistEncoding::kPoolOffsetFreeList: {
static base::NoDestructor<PartitionFreelistDispatcherImpl<
PartitionFreelistEncoding::kPoolOffsetFreeList>>
pool_offset_impl;
return pool_offset_impl.get();
return &kPoolOffsetImplDispatcher;
}
}
}
#endif // PA_BUILDFLAG(USE_FREELIST_DISPATCHER)
} // namespace partition_alloc::internal
#endif // PARTITION_ALLOC_PARTITION_FREELIST_ENTRY_H_
@@ -19,7 +19,7 @@ PA_NOINLINE PA_NOT_TAIL_CALLED void PartitionExcessiveAllocationSize(
OOM_CRASH(size);
}
#if !defined(ARCH_CPU_64_BITS)
#if !PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
PA_NOINLINE PA_NOT_TAIL_CALLED void
PartitionOutOfMemoryWithLotsOfUncommitedPages(size_t size) {
PA_NO_CODE_FOLDING();
@@ -32,6 +32,6 @@ PartitionOutOfMemoryWithLargeVirtualSize(size_t virtual_size) {
OOM_CRASH(virtual_size);
}
#endif // !defined(ARCH_CPU_64_BITS)
#endif // !PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
} // namespace partition_alloc::internal
@@ -26,7 +26,7 @@ extern OomFunction g_oom_handling_function;
[[noreturn]] PA_NOINLINE PA_COMPONENT_EXPORT(
PARTITION_ALLOC) void PartitionExcessiveAllocationSize(size_t size);
#if !defined(ARCH_CPU_64_BITS)
#if !PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
[[noreturn]] PA_NOINLINE void PartitionOutOfMemoryWithLotsOfUncommitedPages(
size_t size);
[[noreturn]] PA_NOINLINE void PartitionOutOfMemoryWithLargeVirtualSize(

Some files were not shown because too many files have changed in this diff Show More