diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc | 113 |
1 files changed, 72 insertions, 41 deletions
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc index e6c60b06bd2..8621cb4d6b5 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc @@ -35,6 +35,7 @@ #include "base/allocator/partition_allocator/page_allocator.h" #include "base/allocator/partition_allocator/partition_alloc_features.h" #include "base/debug/alias.h" +#include "base/no_destructor.h" #include "base/strings/safe_sprintf.h" #include "base/thread_annotations.h" #include "components/crash/core/common/crash_key.h" @@ -46,11 +47,19 @@ namespace WTF { const char* const Partitions::kAllocatedObjectPoolName = "partition_alloc/allocated_objects"; +#if PA_ALLOW_PCSCAN +// Runs PCScan on WTF partitions. +const base::Feature kPCScanBlinkPartitions{"PCScanBlinkPartitions", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + bool Partitions::initialized_ = false; // These statics are inlined, so cannot be LazyInstances. We create the values, // and then set the pointers correctly in Initialize(). +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) base::ThreadSafePartitionRoot* Partitions::fast_malloc_root_ = nullptr; +#endif base::ThreadSafePartitionRoot* Partitions::array_buffer_root_ = nullptr; base::ThreadSafePartitionRoot* Partitions::buffer_root_ = nullptr; base::ThreadUnsafePartitionRoot* Partitions::layout_root_ = nullptr; @@ -63,50 +72,52 @@ void Partitions::Initialize() { // static bool Partitions::InitializeOnce() { - static base::PartitionAllocator fast_malloc_allocator{}; - static base::PartitionAllocator array_buffer_allocator{}; - static base::PartitionAllocator buffer_allocator{}; - static base::ThreadUnsafePartitionAllocator layout_allocator{}; +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + static base::NoDestructor<base::PartitionAllocator> fast_malloc_allocator{}; + fast_malloc_allocator->init({base::PartitionOptions::Alignment::kRegular, + base::PartitionOptions::ThreadCache::kEnabled, + base::PartitionOptions::Quarantine::kAllowed, + base::PartitionOptions::RefCount::kDisabled}); + + fast_malloc_root_ = fast_malloc_allocator->root(); +#endif // !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + + static base::NoDestructor<base::PartitionAllocator> array_buffer_allocator{}; + static base::NoDestructor<base::PartitionAllocator> buffer_allocator{}; + static base::NoDestructor<base::ThreadUnsafePartitionAllocator> + layout_allocator{}; base::PartitionAllocGlobalInit(&Partitions::HandleOutOfMemory); - // Restrictions: - // - DCHECK_IS_ON(): Memory usage of the thread cache is not optimized yet, - // don't ship this. - // - BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC): Only one thread cache at a time - // is supported, in this case it is already claimed by malloc(). -#if DCHECK_IS_ON() && !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) - fast_malloc_allocator.init( - {base::PartitionOptions::Alignment::kRegular, - base::PartitionOptions::ThreadCache::kEnabled, - base::PartitionOptions::PCScan::kDisabledByDefault}); -#else - fast_malloc_allocator.init( - {base::PartitionOptions::Alignment::kRegular, - base::PartitionOptions::ThreadCache::kDisabled, - base::PartitionOptions::PCScan::kDisabledByDefault}); + array_buffer_allocator->init({base::PartitionOptions::Alignment::kRegular, + base::PartitionOptions::ThreadCache::kDisabled, + base::PartitionOptions::Quarantine::kAllowed, + base::PartitionOptions::RefCount::kDisabled}); + buffer_allocator->init({base::PartitionOptions::Alignment::kRegular, + base::PartitionOptions::ThreadCache::kDisabled, + base::PartitionOptions::Quarantine::kAllowed, + base::PartitionOptions::RefCount::kDisabled}); + layout_allocator->init({base::PartitionOptions::Alignment::kRegular, + base::PartitionOptions::ThreadCache::kDisabled, + base::PartitionOptions::Quarantine::kAllowed, + base::PartitionOptions::RefCount::kDisabled}); + + array_buffer_root_ = array_buffer_allocator->root(); + buffer_root_ = buffer_allocator->root(); + layout_root_ = layout_allocator->root(); + +#if PA_ALLOW_PCSCAN + if (base::FeatureList::IsEnabled(base::features::kPartitionAllocPCScan) || + base::FeatureList::IsEnabled(kPCScanBlinkPartitions)) { + auto& pcscan = + base::internal::PCScan<base::internal::ThreadSafe>::Instance(); + pcscan.RegisterNonScannableRoot(array_buffer_root_); +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + pcscan.RegisterScannableRoot(fast_malloc_root_); #endif - array_buffer_allocator.init( - {base::PartitionOptions::Alignment::kRegular, - base::PartitionOptions::ThreadCache::kDisabled, - base::PartitionOptions::PCScan::kAlwaysDisabled}); - buffer_allocator.init({base::PartitionOptions::Alignment::kRegular, - base::PartitionOptions::ThreadCache::kDisabled, - base::PartitionOptions::PCScan::kDisabledByDefault}); - layout_allocator.init({base::PartitionOptions::Alignment::kRegular, - base::PartitionOptions::ThreadCache::kDisabled, - base::PartitionOptions::PCScan::kDisabledByDefault}); - - fast_malloc_root_ = fast_malloc_allocator.root(); - array_buffer_root_ = array_buffer_allocator.root(); - buffer_root_ = buffer_allocator.root(); - layout_root_ = layout_allocator.root(); - - if (base::features::IsPartitionAllocPCScanEnabled()) { - fast_malloc_root_->EnablePCScan(); - buffer_root_->EnablePCScan(); - layout_root_->EnablePCScan(); + pcscan.RegisterScannableRoot(buffer_root_); } +#endif initialized_ = true; return initialized_; @@ -129,8 +140,10 @@ void Partitions::DumpMemoryStats( // accessed only on the main thread. DCHECK(IsMainThread()); +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) FastMallocPartition()->DumpStats("fast_malloc", is_light_dump, partition_stats_dumper); +#endif ArrayBufferPartition()->DumpStats("array_buffer", is_light_dump, partition_stats_dumper); BufferPartition()->DumpStats("buffer", is_light_dump, partition_stats_dumper); @@ -166,8 +179,10 @@ size_t Partitions::TotalSizeOfCommittedPages() { DCHECK(initialized_); size_t total_size = 0; // Racy reads below: this is fine to collect statistics. +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) total_size += TS_UNCHECKED_READ(FastMallocPartition()->total_size_of_committed_pages); +#endif total_size += TS_UNCHECKED_READ(ArrayBufferPartition()->total_size_of_committed_pages); total_size += @@ -256,24 +271,40 @@ void Partitions::BufferFree(void* p) { } // static -size_t Partitions::BufferActualSize(size_t n) { - return BufferPartition()->ActualSize(n); +size_t Partitions::BufferPotentialCapacity(size_t n) { + return BufferPartition()->AllocationCapacityFromRequestedSize(n); } +// Ideally this would be removed when PartitionAlloc is malloc(), but there are +// quite a few callers. Just forward to the C functions instead. Most of the +// usual callers will never reach here though, as USING_FAST_MALLOC() becomes a +// no-op. // static void* Partitions::FastMalloc(size_t n, const char* type_name) { +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) return FastMallocPartition()->Alloc(n, type_name); +#else + return malloc(n); +#endif } // static void* Partitions::FastZeroedMalloc(size_t n, const char* type_name) { +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) return FastMallocPartition()->AllocFlags(base::PartitionAllocZeroFill, n, type_name); +#else + return calloc(n, 1); +#endif } // static void Partitions::FastFree(void* p) { +#if !BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) FastMallocPartition()->Free(p); +#else + free(p); +#endif } // static |