1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/trace_event/address_space_dump_provider.h"
6
7 #include "base/allocator/partition_allocator/address_pool_manager.h"
8 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
9 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
10 #include "base/no_destructor.h"
11 #include "base/trace_event/memory_allocator_dump.h"
12 #include "base/trace_event/process_memory_dump.h"
13
14 namespace base::trace_event {
15
16 namespace {
17
18 using ::partition_alloc::internal::kSuperPageSize;
19
20 // Implements the rendezvous interface that shuttles figures out of the
21 // `AddressSpaceStatsDumper`.
22 class AddressSpaceStatsDumperImpl final
23 : public partition_alloc::AddressSpaceStatsDumper {
24 public:
AddressSpaceStatsDumperImpl(ProcessMemoryDump * memory_dump)25 explicit AddressSpaceStatsDumperImpl(ProcessMemoryDump* memory_dump)
26 : memory_dump_(memory_dump) {}
27 ~AddressSpaceStatsDumperImpl() = default;
28
DumpStats(const partition_alloc::AddressSpaceStats * address_space_stats)29 void DumpStats(
30 const partition_alloc::AddressSpaceStats* address_space_stats) override {
31 MemoryAllocatorDump* dump =
32 memory_dump_->CreateAllocatorDump("partition_alloc/address_space");
33
34 // Regular pool usage is applicable everywhere.
35 dump->AddScalar(
36 "regular_pool_usage", MemoryAllocatorDump::kUnitsBytes,
37 address_space_stats->regular_pool_stats.usage * kSuperPageSize);
38
39 // BRP pool usage is applicable with the appropriate buildflag.
40 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
41 dump->AddScalar("brp_pool_usage", MemoryAllocatorDump::kUnitsBytes,
42 address_space_stats->brp_pool_stats.usage * kSuperPageSize);
43 #endif // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
44
45 // The configurable pool is only available on 64-bit platforms.
46 #if BUILDFLAG(HAS_64_BIT_POINTERS)
47 dump->AddScalar(
48 "configurable_pool_usage", MemoryAllocatorDump::kUnitsBytes,
49 address_space_stats->configurable_pool_stats.usage * kSuperPageSize);
50 #endif // BUILDFLAG(HAS_64_BIT_POINTERS)
51
52 // Pkey pool usage is applicable with the appropriate buildflag.
53 #if BUILDFLAG(ENABLE_PKEYS)
54 dump->AddScalar(
55 "pkey_pool_usage", MemoryAllocatorDump::kUnitsBytes,
56 address_space_stats->pkey_pool_stats.usage * kSuperPageSize);
57 #endif // BUILDFLAG(ENABLE_PKEYS)
58
59 // Additionally, largest possible reservation is also available on
60 // 64-bit platforms.
61 #if BUILDFLAG(HAS_64_BIT_POINTERS)
62 dump->AddScalar(
63 "regular_pool_largest_reservation", MemoryAllocatorDump::kUnitsBytes,
64 address_space_stats->regular_pool_stats.largest_available_reservation *
65 kSuperPageSize);
66 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
67 dump->AddScalar(
68 "brp_pool_largest_reservation", MemoryAllocatorDump::kUnitsBytes,
69 address_space_stats->brp_pool_stats.largest_available_reservation *
70 kSuperPageSize);
71 #endif // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
72 dump->AddScalar("configurable_pool_largest_reservation",
73 MemoryAllocatorDump::kUnitsBytes,
74 address_space_stats->configurable_pool_stats
75 .largest_available_reservation *
76 kSuperPageSize);
77 #if BUILDFLAG(ENABLE_PKEYS)
78 dump->AddScalar(
79 "pkey_pool_largest_reservation", MemoryAllocatorDump::kUnitsBytes,
80 address_space_stats->pkey_pool_stats.largest_available_reservation *
81 kSuperPageSize);
82 #endif // BUILDFLAG(ENABLE_PKEYS)
83 #endif // BUILDFLAG(HAS_64_BIT_POINTERS)
84
85 #if !BUILDFLAG(HAS_64_BIT_POINTERS) && BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
86 dump->AddScalar("blocklist_size", MemoryAllocatorDump::kUnitsObjects,
87 address_space_stats->blocklist_size);
88 dump->AddScalar("blocklist_hit_count", MemoryAllocatorDump::kUnitsObjects,
89 address_space_stats->blocklist_hit_count);
90 #endif // !BUILDFLAG(HAS_64_BIT_POINTERS) &&
91 // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
92 return;
93 }
94
95 private:
96 raw_ptr<base::trace_event::ProcessMemoryDump> memory_dump_;
97 };
98
99 } // namespace
100
101 AddressSpaceDumpProvider::AddressSpaceDumpProvider() = default;
102 AddressSpaceDumpProvider::~AddressSpaceDumpProvider() = default;
103
104 // static
GetInstance()105 AddressSpaceDumpProvider* AddressSpaceDumpProvider::GetInstance() {
106 static base::NoDestructor<AddressSpaceDumpProvider> instance;
107 return instance.get();
108 }
109
110 // MemoryDumpProvider implementation.
OnMemoryDump(const MemoryDumpArgs & args,ProcessMemoryDump * pmd)111 bool AddressSpaceDumpProvider::OnMemoryDump(const MemoryDumpArgs& args,
112 ProcessMemoryDump* pmd) {
113 AddressSpaceStatsDumperImpl stats_dumper(pmd);
114 partition_alloc::internal::AddressPoolManager::GetInstance().DumpStats(
115 &stats_dumper);
116 return true;
117 }
118
119 } // namespace base::trace_event
120