#include "base/allocator/partition_alloc_support.h"
#include <array>
#include <cinttypes>
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <string_view>
#include "base/allocator/partition_alloc_features.h"
#include "base/at_exit.h"
#include "base/check.h"
#include "base/containers/span.h"
#include "base/cpu.h"
#include "base/debug/dump_without_crashing.h"
#include "base/debug/stack_trace.h"
#include "base/debug/task_trace.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/immediate_crash.h"
#include "base/location.h"
#include "base/memory/post_delayed_memory_reduction_task.h"
#include "base/memory/raw_ptr_asan_service.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/pending_task.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/task/single_thread_task_runner.h"
#include "base/thread_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/base_tracing.h"
#include "build/build_config.h"
#include "partition_alloc/allocation_guard.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/dangling_raw_ptr_checks.h"
#include "partition_alloc/memory_reclaimer.h"
#include "partition_alloc/page_allocator.h"
#include "partition_alloc/partition_alloc_base/debug/alias.h"
#include "partition_alloc/partition_alloc_base/threading/platform_thread.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"
#include "partition_alloc/pointers/raw_ptr.h"
#include "partition_alloc/shim/allocator_shim.h"
#include "partition_alloc/shim/allocator_shim_default_dispatch_to_partition_alloc.h"
#include "partition_alloc/stack/stack.h"
#include "partition_alloc/thread_cache.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/system/sys_info.h"
#endif
#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#include "partition_alloc/memory_reclaimer.h"
#endif
#if BUILDFLAG(IS_ANDROID) && PA_BUILDFLAG(HAS_MEMORY_TAGGING)
#include <sys/system_properties.h>
#endif
namespace base::allocator {
namespace {
#if BUILDFLAG(IS_ANDROID) && PA_BUILDFLAG(HAS_MEMORY_TAGGING)
enum class BootloaderOverride {
kDefault,
kForceOn,
kForceOff,
};
BootloaderOverride GetBootloaderOverride() {
char bootloader_override_str[PROP_VALUE_MAX];
__system_property_get(
"persist.device_config.runtime_native_boot.bootloader_override",
bootloader_override_str);
if (strcmp(bootloader_override_str, "force_on") == 0) {
return BootloaderOverride::kForceOn;
}
if (strcmp(bootloader_override_str, "force_off") == 0) {
return BootloaderOverride::kForceOff;
}
return BootloaderOverride::kDefault;
}
#endif
static BASE_FEATURE(kDelayFirstPeriodicPAPurgeOrReclaim,
"DelayFirstPeriodicPAPurgeOrReclaim",
base::FEATURE_ENABLED_BY_DEFAULT);
constexpr base::TimeDelta kFirstPAPurgeOrReclaimDelay = …;
namespace switches {
[[maybe_unused]] constexpr char kRendererProcess[] = …;
constexpr char kZygoteProcess[] = …;
}
}
namespace {
void RunThreadCachePeriodicPurge() { … }
}
BASE_FEATURE(…);
BASE_FEATURE(…);
MemoryReclaimerSupport& MemoryReclaimerSupport::Instance() { … }
MemoryReclaimerSupport::~MemoryReclaimerSupport() = default;
MemoryReclaimerSupport::MemoryReclaimerSupport() = default;
void MemoryReclaimerSupport::Start(scoped_refptr<TaskRunner> task_runner) { … }
void MemoryReclaimerSupport::SetForegrounded(bool in_foreground) { … }
void MemoryReclaimerSupport::ResetForTesting() { … }
void MemoryReclaimerSupport::Run() { … }
TimeDelta MemoryReclaimerSupport::GetInterval() { … }
void MemoryReclaimerSupport::MaybeScheduleTask(TimeDelta delay) { … }
void StartThreadCachePeriodicPurge() { … }
void StartMemoryReclaimer(scoped_refptr<SequencedTaskRunner> task_runner) { … }
std::map<std::string, std::string> ProposeSyntheticFinchTrials() { … }
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
namespace {
internal::PartitionLock g_stack_trace_buffer_lock;
constexpr size_t kDanglingPtrStackTraceSize = …;
struct DanglingPointerFreeInfo { … };
DanglingRawPtrBuffer;
DanglingRawPtrBuffer g_stack_trace_buffer GUARDED_BY(…) …;
void DanglingRawPtrDetected(uintptr_t id) { … }
std::optional<DanglingPointerFreeInfo> TakeDanglingPointerFreeInfo(
uintptr_t id) { … }
std::string ExtractDanglingPtrSignature(std::string stacktrace) { … }
std::string ExtractDanglingPtrSignature(debug::TaskTrace task_trace) { … }
std::string ExtractDanglingPtrSignature(
std::optional<DanglingPointerFreeInfo> free_info,
debug::StackTrace release_stack_trace,
debug::TaskTrace release_task_trace) { … }
bool operator==(const debug::TaskTrace& lhs, const debug::TaskTrace& rhs) { … }
template <features::DanglingPtrMode dangling_pointer_mode,
features::DanglingPtrType dangling_pointer_type>
void DanglingRawPtrReleased(uintptr_t id) { … }
void CheckDanglingRawPtrBufferEmpty() { … }
}
void InstallDanglingRawPtrChecks() { … }
#else
void InstallDanglingRawPtrChecks() {}
#endif
void UnretainedDanglingRawPtrDetectedDumpWithoutCrashing(uintptr_t id) { … }
void UnretainedDanglingRawPtrDetectedCrash(uintptr_t id) { … }
void InstallUnretainedDanglingRawPtrChecks() { … }
void ReconfigurePartitionForKnownProcess(const std::string& process_type) { … }
PartitionAllocSupport* PartitionAllocSupport::Get() { … }
PartitionAllocSupport::PartitionAllocSupport() = default;
void PartitionAllocSupport::ReconfigureForTests() { … }
bool PartitionAllocSupport::ShouldEnableMemoryTagging(
const std::string& process_type) { … }
bool PartitionAllocSupport::ShouldEnableMemoryTaggingInRendererProcess() { … }
PartitionAllocSupport::BrpConfiguration
PartitionAllocSupport::GetBrpConfiguration(const std::string& process_type) { … }
void PartitionAllocSupport::ReconfigureEarlyish(
const std::string& process_type) { … }
void PartitionAllocSupport::ReconfigureAfterZygoteFork(
const std::string& process_type) { … }
void PartitionAllocSupport::ReconfigureAfterFeatureListInit(
const std::string& process_type,
bool configure_dangling_pointer_detector) { … }
void PartitionAllocSupport::ReconfigureAfterTaskRunnerInit(
const std::string& process_type) { … }
void PartitionAllocSupport::OnForegrounded(bool has_main_frame) { … }
void PartitionAllocSupport::OnBackgrounded() { … }
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
std::string PartitionAllocSupport::ExtractDanglingPtrSignatureForTests(
std::string stacktrace) { … }
#endif
}