• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/no_destructor.h"
8 #include "base/trace_event/memory_allocator_dump.h"
9 #include "base/trace_event/process_memory_dump.h"
10 #include "partition_alloc/address_pool_manager.h"
11 #include "partition_alloc/buildflags.h"
12 #include "partition_alloc/partition_alloc_constants.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() final = 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 PA_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  // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
44 
45     // The configurable pool is only available on 64-bit platforms.
46 #if PA_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  // PA_BUILDFLAG(HAS_64_BIT_POINTERS)
51 
52     // Thread isolated pool usage is applicable with the appropriate buildflag.
53 #if PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
54     dump->AddScalar(
55         "thread_isolated_pool_usage", MemoryAllocatorDump::kUnitsBytes,
56         address_space_stats->thread_isolated_pool_stats.usage * kSuperPageSize);
57 #endif  // PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
58 
59     // Additionally, largest possible reservation is also available on
60     // 64-bit platforms.
61 #if PA_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 PA_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  // PA_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 PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
78     dump->AddScalar("thread_isolated_pool_largest_reservation",
79                     MemoryAllocatorDump::kUnitsBytes,
80                     address_space_stats->thread_isolated_pool_stats
81                             .largest_available_reservation *
82                         kSuperPageSize);
83 #endif  // PA_BUILDFLAG(ENABLE_THREAD_ISOLATION)
84 #endif  // PA_BUILDFLAG(HAS_64_BIT_POINTERS)
85 
86 #if !PA_BUILDFLAG(HAS_64_BIT_POINTERS) && \
87     PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
88     dump->AddScalar("blocklist_size", MemoryAllocatorDump::kUnitsObjects,
89                     address_space_stats->blocklist_size);
90     dump->AddScalar("blocklist_hit_count", MemoryAllocatorDump::kUnitsObjects,
91                     address_space_stats->blocklist_hit_count);
92 #endif  // !PA_BUILDFLAG(HAS_64_BIT_POINTERS) &&
93         // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
94     return;
95   }
96 
97  private:
98   raw_ptr<base::trace_event::ProcessMemoryDump> memory_dump_;
99 };
100 
101 }  // namespace
102 
103 AddressSpaceDumpProvider::AddressSpaceDumpProvider() = default;
104 AddressSpaceDumpProvider::~AddressSpaceDumpProvider() = default;
105 
106 // static
GetInstance()107 AddressSpaceDumpProvider* AddressSpaceDumpProvider::GetInstance() {
108   static base::NoDestructor<AddressSpaceDumpProvider> instance;
109   return instance.get();
110 }
111 
112 // MemoryDumpProvider implementation.
OnMemoryDump(const MemoryDumpArgs & args,ProcessMemoryDump * pmd)113 bool AddressSpaceDumpProvider::OnMemoryDump(const MemoryDumpArgs& args,
114                                             ProcessMemoryDump* pmd) {
115   AddressSpaceStatsDumperImpl stats_dumper(pmd);
116   partition_alloc::internal::AddressPoolManager::GetInstance().DumpStats(
117       &stats_dumper);
118   return true;
119 }
120 
121 }  // namespace base::trace_event
122