mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-23 00:17:16 +08:00
Update On Sat Jul 27 20:32:02 CEST 2024
This commit is contained in:
@@ -1 +1 @@
|
||||
126.0.6478.40
|
||||
127.0.6533.64
|
||||
|
||||
@@ -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
@@ -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 =
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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" ]
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
+6
-4
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+27
-27
@@ -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
|
||||
|
||||
|
||||
+2
-2
@@ -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_
|
||||
|
||||
+502
-2
@@ -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_
|
||||
|
||||
+17
@@ -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]
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
+2
-2
@@ -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);
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+9
-6
@@ -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);
|
||||
}
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
+7
@@ -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.
|
||||
|
||||
+2
@@ -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.
|
||||
|
||||
+8
-8
@@ -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;
|
||||
}
|
||||
|
||||
+3
-3
@@ -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
-11
@@ -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 <<
|
||||
|
||||
+18
-18
@@ -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 it’s
|
||||
// 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
|
||||
|
||||
+225
-43
@@ -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;
|
||||
|
||||
+117
-20
@@ -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.
|
||||
|
||||
+8
-2
@@ -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
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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_;
|
||||
|
||||
+14
-12
@@ -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.
|
||||
|
||||
+20
-18
@@ -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;
|
||||
|
||||
+4
-4
@@ -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;
|
||||
|
||||
+5
-5
@@ -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);
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+2
-2
@@ -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
-13
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
|
||||
+8
-8
@@ -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;
|
||||
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
|
||||
+12
-12
@@ -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_
|
||||
|
||||
+15
-14
@@ -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
|
||||
|
||||
+5
-5
@@ -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
|
||||
|
||||
|
||||
+8
-8
@@ -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') {
|
||||
|
||||
+5
-5
@@ -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, \
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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(); }
|
||||
|
||||
+10
-10
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
|
||||
+6
-6
@@ -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
|
||||
|
||||
+4
-4
@@ -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) {
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+10
-10
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
|
||||
+11
-11
@@ -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
|
||||
}
|
||||
|
||||
+3
-3
@@ -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,
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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) /
|
||||
|
||||
+37
-68
@@ -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
|
||||
|
||||
-65
@@ -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
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
#if PA_BUILDFLAG(IS_IOS)
|
||||
#include <cerrno>
|
||||
#endif
|
||||
|
||||
|
||||
+6
-6
@@ -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();
|
||||
|
||||
+5
-5
@@ -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
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+29
-20
@@ -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_
|
||||
|
||||
+29
-5
@@ -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;
|
||||
|
||||
+83
-54
@@ -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
|
||||
|
||||
+7
-16
@@ -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,
|
||||
|
||||
+17
-12
@@ -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_
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
Reference in New Issue
Block a user