blob: e6de4c292d3cf8580038efa8a655a36646dfffdd [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2015 The Chromium Authors
ssid07386852015-04-14 15:32:372// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakj51d26a42024-04-25 14:23:565#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7#pragma allow_unsafe_buffers
8#endif
9
ssid07386852015-04-14 15:32:3710#include "base/trace_event/malloc_dump_provider.h"
11
avibd1ed052015-12-24 04:03:4412#include <stddef.h>
13
brettw1ce49f62017-04-27 19:42:3214#include <unordered_map>
15
Scott Violet44165792018-02-22 02:08:0816#include "base/allocator/buildflags.h"
siggiba33ec02016-08-26 16:13:0717#include "base/debug/profiler.h"
Keishi Hattori3fa56dd2021-04-15 09:33:0218#include "base/format_macros.h"
Benoit Lize6d5fdab52021-03-02 12:51:4119#include "base/metrics/histogram_functions.h"
Peter Kastinga0b914dc2022-07-14 18:43:1920#include "base/numerics/safe_conversions.h"
Benoit Lize59ede6d32021-03-10 09:16:3321#include "base/strings/stringprintf.h"
avibd1ed052015-12-24 04:03:4422#include "base/trace_event/process_memory_dump.h"
David 'Digit' Turner8e6ae282018-10-26 08:03:5123#include "base/trace_event/traced_value.h"
avibd1ed052015-12-24 04:03:4424#include "build/build_config.h"
Arthur Sonzognifd39d612024-06-26 08:16:2325#include "partition_alloc/buildflags.h"
Etienne Dechamps4dacf2b2024-12-19 16:31:0526
27#if PA_BUILDFLAG(USE_PARTITION_ALLOC)
28#include "partition_alloc/partition_alloc_config.h" // nogncheck
29#include "partition_alloc/partition_bucket_lookup.h" // nogncheck
30#endif
avibd1ed052015-12-24 04:03:4431
Xiaohan Wang38e4ebb2022-01-19 06:57:4332#if BUILDFLAG(IS_APPLE)
ssid3aa02fe2015-11-07 16:15:0733#include <malloc/malloc.h>
34#else
ssid07386852015-04-14 15:32:3735#include <malloc.h>
ssid3aa02fe2015-11-07 16:15:0736#endif
Xiaohan Wang38e4ebb2022-01-19 06:57:4337#if BUILDFLAG(IS_WIN)
siggi7bec59a2016-08-25 20:22:2638#include <windows.h>
39#endif
ssid07386852015-04-14 15:32:3740
Xiaohan Wang38e4ebb2022-01-19 06:57:4341#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Marek Ruszczynski219e3eb72021-06-28 21:23:5142#include <features.h>
43#endif
44
Arthur Sonzogni62e877a2024-04-30 16:09:4345#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Yuki Shiinob94fcd32024-05-02 10:16:1546#include "base/no_destructor.h"
Yuki Shiino985ab91e2024-03-14 07:20:4647#include "partition_alloc/shim/allocator_shim_default_dispatch_to_partition_alloc.h"
Benoit Lize097d9ce32020-10-26 12:33:3948#endif
49
Bartek Nowierskiaf8d5d22023-01-11 11:01:0250#if PA_CONFIG(THREAD_CACHE_ALLOC_STATS)
Etienne Dechamps4dacf2b2024-12-19 16:31:0551#include "partition_alloc/partition_alloc_constants.h" // nogncheck
Benoit Lizea4975192021-07-15 14:32:2952#endif
53
Peter Kasting811504a72025-01-09 03:18:5054namespace base::trace_event {
ssid07386852015-04-14 15:32:3755
primianofd9072162016-03-25 02:13:2856namespace {
Xiaohan Wang38e4ebb2022-01-19 06:57:4357#if BUILDFLAG(IS_WIN)
siggi7bec59a2016-08-25 20:22:2658// A structure containing some information about a given heap.
59struct WinHeapInfo {
siggi7bec59a2016-08-25 20:22:2660 size_t committed_size;
61 size_t uncommitted_size;
62 size_t allocated_size;
63 size_t block_count;
64};
65
kraynovad507292016-11-25 18:01:2366// NOTE: crbug.com/665516
67// Unfortunately, there is no safe way to collect information from secondary
68// heaps due to limitations and racy nature of this piece of WinAPI.
siggi82535f62016-12-06 22:29:0369void WinHeapMemoryDumpImpl(WinHeapInfo* crt_heap_info) {
siggi82535f62016-12-06 22:29:0370 // Iterate through whichever heap our CRT is using.
71 HANDLE crt_heap = reinterpret_cast<HANDLE>(_get_heap_handle());
72 ::HeapLock(crt_heap);
kraynovad507292016-11-25 18:01:2373 PROCESS_HEAP_ENTRY heap_entry;
74 heap_entry.lpData = nullptr;
75 // Walk over all the entries in the main heap.
siggi82535f62016-12-06 22:29:0376 while (::HeapWalk(crt_heap, &heap_entry) != FALSE) {
kraynovad507292016-11-25 18:01:2377 if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
siggi82535f62016-12-06 22:29:0378 crt_heap_info->allocated_size += heap_entry.cbData;
79 crt_heap_info->block_count++;
kraynovad507292016-11-25 18:01:2380 } else if ((heap_entry.wFlags & PROCESS_HEAP_REGION) != 0) {
siggi82535f62016-12-06 22:29:0381 crt_heap_info->committed_size += heap_entry.Region.dwCommittedSize;
82 crt_heap_info->uncommitted_size += heap_entry.Region.dwUnCommittedSize;
liamjmc56e1ffa2016-10-15 01:04:4683 }
siggi7bec59a2016-08-25 20:22:2684 }
siggi82535f62016-12-06 22:29:0385 CHECK(::HeapUnlock(crt_heap) == TRUE);
siggi7bec59a2016-08-25 20:22:2686}
Keishi Hattori3fa56dd2021-04-15 09:33:0287
88void ReportWinHeapStats(MemoryDumpLevelOfDetail level_of_detail,
89 ProcessMemoryDump* pmd,
90 size_t* total_virtual_size,
91 size_t* resident_size,
92 size_t* allocated_objects_size,
93 size_t* allocated_objects_count) {
94 // This is too expensive on Windows, crbug.com/780735.
Ho Cheungadbf3fb2023-09-08 02:01:1195 if (level_of_detail == MemoryDumpLevelOfDetail::kDetailed) {
Keishi Hattori3fa56dd2021-04-15 09:33:0296 WinHeapInfo main_heap_info = {};
97 WinHeapMemoryDumpImpl(&main_heap_info);
98 *total_virtual_size +=
99 main_heap_info.committed_size + main_heap_info.uncommitted_size;
100 // Resident size is approximated with committed heap size. Note that it is
101 // possible to do this with better accuracy on windows by intersecting the
102 // working set with the virtual memory ranges occuipied by the heap. It's
103 // not clear that this is worth it, as it's fairly expensive to do.
104 *resident_size += main_heap_info.committed_size;
105 *allocated_objects_size += main_heap_info.allocated_size;
106 *allocated_objects_count += main_heap_info.block_count;
107
108 if (pmd) {
109 MemoryAllocatorDump* win_heap_dump =
110 pmd->CreateAllocatorDump("malloc/win_heap");
ssid9becc202022-03-25 05:06:20111 win_heap_dump->AddScalar(MemoryAllocatorDump::kNameSize,
112 MemoryAllocatorDump::kUnitsBytes,
113 main_heap_info.allocated_size);
Keishi Hattori3fa56dd2021-04-15 09:33:02114 }
115 }
116}
Xiaohan Wang38e4ebb2022-01-19 06:57:43117#endif // BUILDFLAG(IS_WIN)
Benoit Lize097d9ce32020-10-26 12:33:39118
Arthur Sonzogni62e877a2024-04-30 16:09:43119#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Keishi Hattori3fa56dd2021-04-15 09:33:02120void ReportPartitionAllocStats(ProcessMemoryDump* pmd,
121 MemoryDumpLevelOfDetail level_of_detail,
122 size_t* total_virtual_size,
123 size_t* resident_size,
Benoit Lize8d380a22022-01-06 18:51:34124 size_t* allocated_objects_size,
Keishi Hattorie1464c32022-04-18 19:27:21125 size_t* allocated_objects_count,
Keishi Hattoridb0566a22022-06-28 07:25:38126 uint64_t* syscall_count,
127 size_t* cumulative_brp_quarantined_size,
128 size_t* cumulative_brp_quarantined_count) {
Keishi Hattori3fa56dd2021-04-15 09:33:02129 MemoryDumpPartitionStatsDumper partition_stats_dumper("malloc", pmd,
130 level_of_detail);
Ho Cheungadbf3fb2023-09-08 02:01:11131 bool is_light_dump = level_of_detail == MemoryDumpLevelOfDetail::kBackground;
Anton Bikineevebd5dc32021-03-05 09:12:25132
Yuki Shiino2ff81312022-09-05 13:11:55133 auto* allocator = allocator_shim::internal::PartitionAllocMalloc::Allocator();
Keishi Hattori3fa56dd2021-04-15 09:33:02134 allocator->DumpStats("allocator", is_light_dump, &partition_stats_dumper);
Benoit Lize097d9ce32020-10-26 12:33:39135
Keishi Hattori3fa56dd2021-04-15 09:33:02136 auto* original_allocator =
Yuki Shiino2ff81312022-09-05 13:11:55137 allocator_shim::internal::PartitionAllocMalloc::OriginalAllocator();
Keishi Hattori3fa56dd2021-04-15 09:33:02138 if (original_allocator) {
139 original_allocator->DumpStats("original", is_light_dump,
140 &partition_stats_dumper);
Benoit Lize097d9ce32020-10-26 12:33:39141 }
Benoit Lize9021e2742021-01-11 11:30:32142
Keishi Hattori3fa56dd2021-04-15 09:33:02143 *total_virtual_size += partition_stats_dumper.total_resident_bytes();
Benoit Lized3ad25ac2021-08-17 19:36:47144 *resident_size += partition_stats_dumper.total_resident_bytes();
Keishi Hattori3fa56dd2021-04-15 09:33:02145 *allocated_objects_size += partition_stats_dumper.total_active_bytes();
Keishi Hattorie1464c32022-04-18 19:27:21146 *allocated_objects_count += partition_stats_dumper.total_active_count();
Benoit Lize8d380a22022-01-06 18:51:34147 *syscall_count += partition_stats_dumper.syscall_count();
Arthur Sonzogni62e877a2024-04-30 16:09:43148#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
Keishi Hattoridb0566a22022-06-28 07:25:38149 *cumulative_brp_quarantined_size +=
150 partition_stats_dumper.cumulative_brp_quarantined_bytes();
151 *cumulative_brp_quarantined_count +=
152 partition_stats_dumper.cumulative_brp_quarantined_count();
Arthur Sonzogni62e877a2024-04-30 16:09:43153#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
Benoit Lize097d9ce32020-10-26 12:33:39154}
Arthur Sonzogni62e877a2024-04-30 16:09:43155#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Benoit Lize097d9ce32020-10-26 12:33:39156
Arthur Sonzogni62e877a2024-04-30 16:09:43157#if !PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(IS_APPLE)
ssid9becc202022-03-25 05:06:20158void ReportAppleAllocStats(size_t* total_virtual_size,
159 size_t* resident_size,
160 size_t* allocated_objects_size) {
161 malloc_statistics_t stats = {0};
162 malloc_zone_statistics(nullptr, &stats);
163 *total_virtual_size += stats.size_allocated;
164 *allocated_objects_size += stats.size_in_use;
165
166 // Resident size is approximated pretty well by stats.max_size_in_use.
167 // However, on macOS, freed blocks are both resident and reusable, which is
168 // semantically equivalent to deallocated. The implementation of libmalloc
169 // will also only hold a fixed number of freed regions before actually
170 // starting to deallocate them, so stats.max_size_in_use is also not
171 // representative of the peak size. As a result, stats.max_size_in_use is
172 // typically somewhere between actually resident [non-reusable] pages, and
173 // peak size. This is not very useful, so we just use stats.size_in_use for
174 // resident_size, even though it's an underestimate and fails to account for
175 // fragmentation. See
176 // https://bugs.chromium.org/p/chromium/issues/detail?id=695263#c1.
177 *resident_size += stats.size_in_use;
178}
179#endif
180
Arthur Sonzogni62e877a2024-04-30 16:09:43181#if (PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(IS_ANDROID)) || \
182 (!PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && !BUILDFLAG(IS_WIN) && \
Peter Kastinga0b914dc2022-07-14 18:43:19183 !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_FUCHSIA))
ssid9becc202022-03-25 05:06:20184void ReportMallinfoStats(ProcessMemoryDump* pmd,
185 size_t* total_virtual_size,
186 size_t* resident_size,
187 size_t* allocated_objects_size,
188 size_t* allocated_objects_count) {
189#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
190#if __GLIBC_PREREQ(2, 33)
191#define MALLINFO2_FOUND_IN_LIBC
192 struct mallinfo2 info = mallinfo2();
193#endif
194#endif // defined(__GLIBC__) && defined(__GLIBC_PREREQ)
195#if !defined(MALLINFO2_FOUND_IN_LIBC)
196 struct mallinfo info = mallinfo();
197#endif
198#undef MALLINFO2_FOUND_IN_LIBC
199 // In case of Android's jemalloc |arena| is 0 and the outer pages size is
200 // reported by |hblkhd|. In case of dlmalloc the total is given by
201 // |arena| + |hblkhd|. For more details see link: http://goo.gl/fMR8lF.
Peter Kastinga0b914dc2022-07-14 18:43:19202 *total_virtual_size += checked_cast<size_t>(info.arena + info.hblkhd);
203 size_t total_allocated_size = checked_cast<size_t>(info.uordblks);
204 *resident_size += total_allocated_size;
ssid9becc202022-03-25 05:06:20205
206 // Total allocated space is given by |uordblks|.
Peter Kastinga0b914dc2022-07-14 18:43:19207 *allocated_objects_size += total_allocated_size;
ssid9becc202022-03-25 05:06:20208
209 if (pmd) {
210 MemoryAllocatorDump* sys_alloc_dump =
211 pmd->CreateAllocatorDump("malloc/sys_malloc");
212 sys_alloc_dump->AddScalar(MemoryAllocatorDump::kNameSize,
Peter Kastinga0b914dc2022-07-14 18:43:19213 MemoryAllocatorDump::kUnitsBytes,
214 total_allocated_size);
ssid9becc202022-03-25 05:06:20215 }
216}
217#endif
218
Arthur Sonzogni62e877a2024-04-30 16:09:43219#if PA_BUILDFLAG(USE_PARTITION_ALLOC)
Kalvin Lee01b3850d2022-06-15 22:41:55220void ReportPartitionAllocThreadCacheStats(
221 ProcessMemoryDump* pmd,
222 MemoryAllocatorDump* dump,
223 const partition_alloc::ThreadCacheStats& stats,
224 const std::string& metrics_suffix,
225 bool detailed) {
ssid9becc202022-03-25 05:06:20226 dump->AddScalar("alloc_count", MemoryAllocatorDump::kTypeScalar,
227 stats.alloc_count);
228 dump->AddScalar("alloc_hits", MemoryAllocatorDump::kTypeScalar,
229 stats.alloc_hits);
230 dump->AddScalar("alloc_misses", MemoryAllocatorDump::kTypeScalar,
231 stats.alloc_misses);
232
233 dump->AddScalar("alloc_miss_empty", MemoryAllocatorDump::kTypeScalar,
234 stats.alloc_miss_empty);
235 dump->AddScalar("alloc_miss_too_large", MemoryAllocatorDump::kTypeScalar,
236 stats.alloc_miss_too_large);
237
238 dump->AddScalar("cache_fill_count", MemoryAllocatorDump::kTypeScalar,
239 stats.cache_fill_count);
240 dump->AddScalar("cache_fill_hits", MemoryAllocatorDump::kTypeScalar,
241 stats.cache_fill_hits);
242 dump->AddScalar("cache_fill_misses", MemoryAllocatorDump::kTypeScalar,
243 stats.cache_fill_misses);
244
245 dump->AddScalar("batch_fill_count", MemoryAllocatorDump::kTypeScalar,
246 stats.batch_fill_count);
247
248 dump->AddScalar(MemoryAllocatorDump::kNameSize,
249 MemoryAllocatorDump::kUnitsBytes, stats.bucket_total_memory);
250 dump->AddScalar("metadata_overhead", MemoryAllocatorDump::kUnitsBytes,
251 stats.metadata_overhead);
252
Bartek Nowierskiaf8d5d22023-01-11 11:01:02253#if PA_CONFIG(THREAD_CACHE_ALLOC_STATS)
Kalvin Lee7800f5c62024-06-20 11:59:12254 if (stats.alloc_count && detailed) {
255 partition_alloc::internal::BucketIndexLookup lookup{};
256 std::string name = dump->absolute_name();
257 for (size_t i = 0; i < partition_alloc::kNumBuckets; i++) {
258 size_t bucket_size = lookup.bucket_sizes()[i];
259 if (bucket_size == partition_alloc::kInvalidBucketSize) {
260 continue;
ssid9becc202022-03-25 05:06:20261 }
Kalvin Lee7800f5c62024-06-20 11:59:12262 // Covers all normal buckets, that is up to ~1MiB, so 7 digits.
263 std::string dump_name = base::StringPrintf(
264 "%s/buckets_alloc/%07d", name.c_str(), static_cast<int>(bucket_size));
265 auto* buckets_alloc_dump = pmd->CreateAllocatorDump(dump_name);
266 buckets_alloc_dump->AddScalar("count", MemoryAllocatorDump::kUnitsObjects,
267 stats.allocs_per_bucket_[i]);
ssid9becc202022-03-25 05:06:20268 }
ssid9becc202022-03-25 05:06:20269 }
Kalvin Lee7800f5c62024-06-20 11:59:12270#endif // PA_CONFIG(THREAD_CACHE_ALLOC_STATS)
ssid9becc202022-03-25 05:06:20271}
miktf85547d2024-03-13 09:06:20272
273void ReportPartitionAllocLightweightQuarantineStats(
274 MemoryAllocatorDump* dump,
275 const partition_alloc::LightweightQuarantineStats& stats) {
276 dump->AddScalar("count", MemoryAllocatorDump::kUnitsObjects, stats.count);
277 dump->AddScalar("size_in_bytes", MemoryAllocatorDump::kUnitsBytes,
278 stats.size_in_bytes);
279 dump->AddScalar("cumulative_count", MemoryAllocatorDump::kUnitsObjects,
280 stats.cumulative_count);
281 dump->AddScalar("cumulative_size_in_bytes", MemoryAllocatorDump::kUnitsBytes,
282 stats.cumulative_size_in_bytes);
283 dump->AddScalar("quarantine_miss_count", MemoryAllocatorDump::kUnitsObjects,
284 stats.quarantine_miss_count);
285}
Arthur Sonzogni62e877a2024-04-30 16:09:43286#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC)
ssid9becc202022-03-25 05:06:20287
siggi7bec59a2016-08-25 20:22:26288} // namespace
289
ssid07386852015-04-14 15:32:37290// static
primianofadec05e2015-06-03 16:57:32291const char MallocDumpProvider::kAllocatedObjects[] = "malloc/allocated_objects";
292
293// static
ssid07386852015-04-14 15:32:37294MallocDumpProvider* MallocDumpProvider::GetInstance() {
295 return Singleton<MallocDumpProvider,
296 LeakySingletonTraits<MallocDumpProvider>>::get();
297}
298
Arthur Sonzogni62e877a2024-04-30 16:09:43299#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Yuki Shiinoc56607c82024-04-22 09:26:40300// static
Yuki Shiinoc56607c82024-04-22 09:26:40301void MallocDumpProvider::SetExtremeLUDGetStatsCallback(
302 ExtremeLUDGetStatsCallback callback) {
Yuki Shiinob94fcd32024-05-02 10:16:15303 DCHECK(!callback.is_null());
304 auto& extreme_lud_get_stats_callback = GetExtremeLUDGetStatsCallback();
305 DCHECK(extreme_lud_get_stats_callback.is_null());
306 extreme_lud_get_stats_callback = std::move(callback);
307}
308
309// static
310MallocDumpProvider::ExtremeLUDGetStatsCallback&
311MallocDumpProvider::GetExtremeLUDGetStatsCallback() {
312 static NoDestructor<MallocDumpProvider::ExtremeLUDGetStatsCallback>
313 extreme_lud_get_stats_callback;
314 return *extreme_lud_get_stats_callback;
Yuki Shiinoc56607c82024-04-22 09:26:40315}
Arthur Sonzogni62e877a2024-04-30 16:09:43316#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Yuki Shiinoc56607c82024-04-22 09:26:40317
erikchen37097a92018-05-22 20:28:47318MallocDumpProvider::MallocDumpProvider() = default;
Chris Watkinsbb7211c2017-11-29 07:16:38319MallocDumpProvider::~MallocDumpProvider() = default;
ssid07386852015-04-14 15:32:37320
321// Called at trace dump point time. Creates a snapshot the memory counters for
322// the current process.
ssid90694aeec2015-08-06 13:01:30323bool MallocDumpProvider::OnMemoryDump(const MemoryDumpArgs& args,
324 ProcessMemoryDump* pmd) {
Erik Chen4f64989c2017-11-10 18:15:53325 {
326 base::AutoLock auto_lock(emit_metrics_on_memory_dump_lock_);
ssid9becc202022-03-25 05:06:20327 if (!emit_metrics_on_memory_dump_) {
Erik Chen4f64989c2017-11-10 18:15:53328 return true;
ssid9becc202022-03-25 05:06:20329 }
Erik Chen4f64989c2017-11-10 18:15:53330 }
331
ssid09434092015-10-26 23:05:04332 size_t total_virtual_size = 0;
333 size_t resident_size = 0;
334 size_t allocated_objects_size = 0;
siggi7bec59a2016-08-25 20:22:26335 size_t allocated_objects_count = 0;
Benoit Lize8d380a22022-01-06 18:51:34336 uint64_t syscall_count = 0;
Keishi Hattoridb0566a22022-06-28 07:25:38337 size_t cumulative_brp_quarantined_size = 0;
338 size_t cumulative_brp_quarantined_count = 0;
Arthur Sonzogni62e877a2024-04-30 16:09:43339#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Benoit Lize2c3690842022-01-14 12:03:57340 uint64_t pa_only_resident_size;
341 uint64_t pa_only_allocated_objects_size;
Benoit Lize8d380a22022-01-06 18:51:34342#endif
Benoit Lize097d9ce32020-10-26 12:33:39343
Arthur Sonzogni62e877a2024-04-30 16:09:43344#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Keishi Hattoridb0566a22022-06-28 07:25:38345 ReportPartitionAllocStats(
346 pmd, args.level_of_detail, &total_virtual_size, &resident_size,
347 &allocated_objects_size, &allocated_objects_count, &syscall_count,
348 &cumulative_brp_quarantined_size, &cumulative_brp_quarantined_count);
Keishi Hattori3fa56dd2021-04-15 09:33:02349
Benoit Lize2c3690842022-01-14 12:03:57350 pa_only_resident_size = resident_size;
351 pa_only_allocated_objects_size = allocated_objects_size;
352
ssid9becc202022-03-25 05:06:20353 // Even when PartitionAlloc is used, WinHeap / System malloc is still used as
354 // well, report its statistics.
355#if BUILDFLAG(IS_ANDROID)
356 ReportMallinfoStats(pmd, &total_virtual_size, &resident_size,
357 &allocated_objects_size, &allocated_objects_count);
358#elif BUILDFLAG(IS_WIN)
Keishi Hattori3fa56dd2021-04-15 09:33:02359 ReportWinHeapStats(args.level_of_detail, pmd, &total_virtual_size,
360 &resident_size, &allocated_objects_size,
361 &allocated_objects_count);
ssid9becc202022-03-25 05:06:20362#endif // BUILDFLAG(IS_ANDROID), BUILDFLAG(IS_WIN)
ssid86f78c12015-12-21 11:45:32363
ssid9becc202022-03-25 05:06:20364#elif BUILDFLAG(IS_APPLE)
365 ReportAppleAllocStats(&total_virtual_size, &resident_size,
366 &allocated_objects_size);
Xiaohan Wang38e4ebb2022-01-19 06:57:43367#elif BUILDFLAG(IS_WIN)
Keishi Hattori3fa56dd2021-04-15 09:33:02368 ReportWinHeapStats(args.level_of_detail, nullptr, &total_virtual_size,
369 &resident_size, &allocated_objects_size,
370 &allocated_objects_count);
Xiaohan Wang38e4ebb2022-01-19 06:57:43371#elif BUILDFLAG(IS_FUCHSIA)
scottmg6ea9ff3e2017-05-19 00:08:16372// TODO(fuchsia): Port, see https://crbug.com/706592.
ssid3aa02fe2015-11-07 16:15:07373#else
ssid9becc202022-03-25 05:06:20374 ReportMallinfoStats(/*pmd=*/nullptr, &total_virtual_size, &resident_size,
375 &allocated_objects_size, &allocated_objects_count);
ssid3aa02fe2015-11-07 16:15:07376#endif
ssid09434092015-10-26 23:05:04377
primianofadec05e2015-06-03 16:57:32378 MemoryAllocatorDump* outer_dump = pmd->CreateAllocatorDump("malloc");
ssid09434092015-10-26 23:05:04379 outer_dump->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
380 total_virtual_size);
381 outer_dump->AddScalar(MemoryAllocatorDump::kNameSize,
382 MemoryAllocatorDump::kUnitsBytes, resident_size);
ssid07386852015-04-14 15:32:37383
Keishi Hattoricae288d2022-03-16 04:09:57384 MemoryAllocatorDump* inner_dump = pmd->CreateAllocatorDump(kAllocatedObjects);
385 inner_dump->AddScalar(MemoryAllocatorDump::kNameSize,
ssid09434092015-10-26 23:05:04386 MemoryAllocatorDump::kUnitsBytes,
387 allocated_objects_size);
siggi7bec59a2016-08-25 20:22:26388 if (allocated_objects_count != 0) {
Keishi Hattoricae288d2022-03-16 04:09:57389 inner_dump->AddScalar(MemoryAllocatorDump::kNameObjectCount,
siggi7bec59a2016-08-25 20:22:26390 MemoryAllocatorDump::kUnitsObjects,
391 allocated_objects_count);
392 }
ssid07386852015-04-14 15:32:37393
Peter Kasting9e948212022-06-16 18:41:11394 int64_t waste = static_cast<int64_t>(resident_size - allocated_objects_size);
Benoit Lize2c3690842022-01-14 12:03:57395
396 // With PartitionAlloc, reported size under malloc/partitions is the resident
397 // size, so it already includes fragmentation. Meaning that "malloc/"'s size
398 // would double-count fragmentation if we report it under
399 // "malloc/metadata_fragmentation_caches" as well.
400 //
401 // Still report waste, as on some platforms, PartitionAlloc doesn't capture
402 // all of malloc()'s memory footprint.
Arthur Sonzogni62e877a2024-04-30 16:09:43403#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Peter Kasting2f61c8b2022-07-19 23:43:46404 int64_t pa_waste = static_cast<int64_t>(pa_only_resident_size -
405 pa_only_allocated_objects_size);
Benoit Lize2c3690842022-01-14 12:03:57406 waste -= pa_waste;
407#endif
408
409 if (waste > 0) {
Benoit Lizef4e14722022-01-12 10:56:52410 // Explicitly specify why is extra memory resident. In mac and ios it
411 // accounts for the fragmentation and metadata.
ssid86f78c12015-12-21 11:45:32412 MemoryAllocatorDump* other_dump =
413 pmd->CreateAllocatorDump("malloc/metadata_fragmentation_caches");
414 other_dump->AddScalar(MemoryAllocatorDump::kNameSize,
Peter Kasting9e948212022-06-16 18:41:11415 MemoryAllocatorDump::kUnitsBytes,
416 static_cast<uint64_t>(waste));
ssid86f78c12015-12-21 11:45:32417 }
Keishi Hattori3fa56dd2021-04-15 09:33:02418
Yuki Shiinoc56607c82024-04-22 09:26:40419 base::trace_event::MemoryAllocatorDump* partitions_dump = nullptr;
Yuki Shiinoa92092e72024-09-05 07:11:15420 base::trace_event::MemoryAllocatorDump* elud_dump_for_small_objects = nullptr;
421 ExtremeLUDStats elud_stats_for_small_objects;
422 base::trace_event::MemoryAllocatorDump* elud_dump_for_large_objects = nullptr;
423 ExtremeLUDStats elud_stats_for_large_objects;
Arthur Sonzogni62e877a2024-04-30 16:09:43424#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Yuki Shiinoc56607c82024-04-22 09:26:40425 partitions_dump = pmd->CreateAllocatorDump("malloc/partitions");
426 pmd->AddOwnershipEdge(inner_dump->guid(), partitions_dump->guid());
427
Yuki Shiinob94fcd32024-05-02 10:16:15428 auto& extreme_lud_get_stats_callback = GetExtremeLUDGetStatsCallback();
429 if (!extreme_lud_get_stats_callback.is_null()) {
430 // The Extreme LUD is enabled.
Yuki Shiinoa92092e72024-09-05 07:11:15431 elud_dump_for_small_objects =
432 pmd->CreateAllocatorDump("malloc/extreme_lud/small_objects");
433 elud_dump_for_large_objects =
434 pmd->CreateAllocatorDump("malloc/extreme_lud/large_objects");
435 const auto elud_stats_set = extreme_lud_get_stats_callback.Run();
436 elud_stats_for_small_objects = elud_stats_set.for_small_objects;
437 elud_stats_for_large_objects = elud_stats_set.for_large_objects;
438 ReportPartitionAllocLightweightQuarantineStats(
439 elud_dump_for_small_objects, elud_stats_for_small_objects.lq_stats);
440 ReportPartitionAllocLightweightQuarantineStats(
441 elud_dump_for_large_objects, elud_stats_for_large_objects.lq_stats);
Yuki Shiinoc56607c82024-04-22 09:26:40442 }
Arthur Sonzogni62e877a2024-04-30 16:09:43443#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Yuki Shiinoc56607c82024-04-22 09:26:40444
Yuki Shiinoa92092e72024-09-05 07:11:15445 ReportPerMinuteStats(
446 syscall_count, cumulative_brp_quarantined_size,
447 cumulative_brp_quarantined_count, elud_stats_for_small_objects,
448 elud_stats_for_large_objects, outer_dump, partitions_dump,
449 elud_dump_for_small_objects, elud_dump_for_large_objects);
ssid9becc202022-03-25 05:06:20450
451 return true;
452}
453
Keishi Hattoridb0566a22022-06-28 07:25:38454void MallocDumpProvider::ReportPerMinuteStats(
455 uint64_t syscall_count,
456 size_t cumulative_brp_quarantined_bytes,
457 size_t cumulative_brp_quarantined_count,
Yuki Shiinoa92092e72024-09-05 07:11:15458 const ExtremeLUDStats& elud_stats_for_small_objects,
459 const ExtremeLUDStats& elud_stats_for_large_objects,
Keishi Hattoridb0566a22022-06-28 07:25:38460 MemoryAllocatorDump* malloc_dump,
Yuki Shiinoc56607c82024-04-22 09:26:40461 MemoryAllocatorDump* partition_alloc_dump,
Yuki Shiinoa92092e72024-09-05 07:11:15462 MemoryAllocatorDump* elud_dump_for_small_objects,
463 MemoryAllocatorDump* elud_dump_for_large_objects) {
Arthur Sonzogni62e877a2024-04-30 16:09:43464#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Benoit Lize8d380a22022-01-06 18:51:34465 uint64_t new_syscalls = syscall_count - last_syscall_count_;
Keishi Hattoridb0566a22022-06-28 07:25:38466 size_t new_brp_quarantined_bytes =
467 cumulative_brp_quarantined_bytes - last_cumulative_brp_quarantined_bytes_;
468 size_t new_brp_quarantined_count =
469 cumulative_brp_quarantined_count - last_cumulative_brp_quarantined_count_;
Benoit Lize8d380a22022-01-06 18:51:34470 base::TimeDelta time_since_last_dump =
471 base::TimeTicks::Now() - last_memory_dump_time_;
Yuki Shiinoc56607c82024-04-22 09:26:40472 auto seconds_since_last_dump = time_since_last_dump.InSecondsF();
473 uint64_t syscalls_per_minute =
474 static_cast<uint64_t>((60 * new_syscalls) / seconds_since_last_dump);
ssid9becc202022-03-25 05:06:20475 malloc_dump->AddScalar("syscalls_per_minute", "count", syscalls_per_minute);
Keishi Hattoridb0566a22022-06-28 07:25:38476 if (partition_alloc_dump) {
477 size_t brp_quarantined_bytes_per_minute =
Yuki Shiinoc56607c82024-04-22 09:26:40478 (60 * new_brp_quarantined_bytes) / seconds_since_last_dump;
Keishi Hattoridb0566a22022-06-28 07:25:38479 size_t brp_quarantined_count_per_minute =
Yuki Shiinoc56607c82024-04-22 09:26:40480 (60 * new_brp_quarantined_count) / seconds_since_last_dump;
Keishi Hattoridb0566a22022-06-28 07:25:38481 partition_alloc_dump->AddScalar("brp_quarantined_bytes_per_minute",
482 MemoryAllocatorDump::kUnitsBytes,
483 brp_quarantined_bytes_per_minute);
484 partition_alloc_dump->AddScalar("brp_quarantined_count_per_minute",
485 MemoryAllocatorDump::kNameObjectCount,
486 brp_quarantined_count_per_minute);
487 }
Yuki Shiinoa92092e72024-09-05 07:11:15488
Peter Kasting134ef9af2024-12-28 02:30:09489 auto report_elud_per_minute_stats =
490 [time_since_last_dump, seconds_since_last_dump](
491 const ExtremeLUDStats& elud_stats,
492 CumulativeEludStats& last_cumulative_elud_stats,
493 MemoryAllocatorDump* elud_dump) {
494 size_t bytes = elud_stats.lq_stats.cumulative_size_in_bytes -
495 last_cumulative_elud_stats.quarantined_bytes;
496 size_t count = elud_stats.lq_stats.cumulative_count -
497 last_cumulative_elud_stats.quarantined_count;
498 size_t miss_count = elud_stats.lq_stats.quarantine_miss_count -
499 last_cumulative_elud_stats.miss_count;
500 elud_dump->AddScalar("bytes_per_minute",
501 MemoryAllocatorDump::kUnitsBytes,
502 60ull * bytes / seconds_since_last_dump);
503 elud_dump->AddScalar("count_per_minute",
504 MemoryAllocatorDump::kNameObjectCount,
505 60ull * count / seconds_since_last_dump);
506 elud_dump->AddScalar("miss_count_per_minute",
507 MemoryAllocatorDump::kNameObjectCount,
508 60ull * miss_count / seconds_since_last_dump);
509 // Given the following three:
510 // capacity := the quarantine storage space
511 // time := the elapsed time since the last dump
512 // bytes := the consumed/used bytes since the last dump
513 // We can define/calculate the following.
514 // speed := the consuming speed of the quarantine
515 // = bytes / time
516 // quarantined_time
517 // := the time to use up the capacity
518 // (near to how long an object may be quarantined)
519 // = capacity / speed
520 // = capacity / (bytes / time)
521 // = time * capacity / bytes
522 //
523 // Note that objects in the quarantine are randomly evicted. So objects
524 // may stay in the qurantine longer or shorter depending on object
525 // sizes, allocation/deallocation patterns, etc. in addition to pure
526 // randomness. So, this is just a rough estimation, not necessarily to
527 // be the average.
528 if (bytes > 0) {
529 elud_dump->AddScalar(
530 "quarantined_time", "msec",
531 static_cast<uint64_t>(time_since_last_dump.InMilliseconds()) *
532 elud_stats.capacity_in_bytes / bytes);
533 }
534 last_cumulative_elud_stats.quarantined_bytes =
535 elud_stats.lq_stats.cumulative_size_in_bytes;
536 last_cumulative_elud_stats.quarantined_count =
537 elud_stats.lq_stats.cumulative_count;
538 last_cumulative_elud_stats.miss_count =
539 elud_stats.lq_stats.quarantine_miss_count;
540 };
Yuki Shiinoa92092e72024-09-05 07:11:15541 if (elud_dump_for_small_objects) {
542 report_elud_per_minute_stats(elud_stats_for_small_objects,
543 last_cumulative_elud_stats_for_small_objects_,
544 elud_dump_for_small_objects);
545 }
546 if (elud_dump_for_large_objects) {
547 report_elud_per_minute_stats(elud_stats_for_large_objects,
548 last_cumulative_elud_stats_for_large_objects_,
549 elud_dump_for_large_objects);
Yuki Shiinoc56607c82024-04-22 09:26:40550 }
Benoit Lize8d380a22022-01-06 18:51:34551
552 last_memory_dump_time_ = base::TimeTicks::Now();
553 last_syscall_count_ = syscall_count;
Keishi Hattoridb0566a22022-06-28 07:25:38554 last_cumulative_brp_quarantined_bytes_ = cumulative_brp_quarantined_bytes;
555 last_cumulative_brp_quarantined_count_ = cumulative_brp_quarantined_count;
Arthur Sonzogni62e877a2024-04-30 16:09:43556#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
Erik Chen4f64989c2017-11-10 18:15:53557}
558
Arthur Sonzogni62e877a2024-04-30 16:09:43559#if PA_BUILDFLAG(USE_PARTITION_ALLOC)
Keishi Hattori3fa56dd2021-04-15 09:33:02560std::string GetPartitionDumpName(const char* root_name,
561 const char* partition_name) {
562 return base::StringPrintf("%s/%s/%s", root_name,
563 MemoryDumpPartitionStatsDumper::kPartitionsDumpName,
564 partition_name);
565}
566
Keishi Hattoridb0566a22022-06-28 07:25:38567MemoryDumpPartitionStatsDumper::MemoryDumpPartitionStatsDumper(
568 const char* root_name,
569 ProcessMemoryDump* memory_dump,
570 MemoryDumpLevelOfDetail level_of_detail)
571 : root_name_(root_name),
572 memory_dump_(memory_dump),
Ho Cheungadbf3fb2023-09-08 02:01:11573 detailed_(level_of_detail != MemoryDumpLevelOfDetail::kBackground) {}
Keishi Hattoridb0566a22022-06-28 07:25:38574
Keishi Hattori3fa56dd2021-04-15 09:33:02575void MemoryDumpPartitionStatsDumper::PartitionDumpTotals(
576 const char* partition_name,
Kalvin Lee01b3850d2022-06-15 22:41:55577 const partition_alloc::PartitionMemoryStats* memory_stats) {
Keishi Hattori3fa56dd2021-04-15 09:33:02578 total_mmapped_bytes_ += memory_stats->total_mmapped_bytes;
579 total_resident_bytes_ += memory_stats->total_resident_bytes;
580 total_active_bytes_ += memory_stats->total_active_bytes;
Keishi Hattorie1464c32022-04-18 19:27:21581 total_active_count_ += memory_stats->total_active_count;
Benoit Lize8d380a22022-01-06 18:51:34582 syscall_count_ += memory_stats->syscall_count;
Arthur Sonzogni62e877a2024-04-30 16:09:43583#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
Keishi Hattoridb0566a22022-06-28 07:25:38584 cumulative_brp_quarantined_bytes_ +=
585 memory_stats->cumulative_brp_quarantined_bytes;
586 cumulative_brp_quarantined_count_ +=
587 memory_stats->cumulative_brp_quarantined_count;
Arthur Sonzogni62e877a2024-04-30 16:09:43588#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
Keishi Hattori3fa56dd2021-04-15 09:33:02589
590 std::string dump_name = GetPartitionDumpName(root_name_, partition_name);
591 MemoryAllocatorDump* allocator_dump =
592 memory_dump_->CreateAllocatorDump(dump_name);
Thiabaud Engelbrechtff1e1072021-11-13 01:49:41593
594 auto total_committed_bytes = memory_stats->total_committed_bytes;
595 auto total_active_bytes = memory_stats->total_active_bytes;
Benoît Lizé240f9b72025-01-27 11:15:28596 size_t wasted = 0;
597 // This should always be true, but only if our accounting of committed bytes
598 // is consistent, which it isn't. Indeed, with
599 // PartitionAllocFewerMemoryRegions, we may allocate a slot span before the
600 // feature state is known, in which case we commit less, then decommit it
601 // after, in which case we subtract the new commit unit, which is larger.
602 //
603 // Properly handling this would require remembering how much was committed,
604 // which complicates bookkeeping, especially as metadata space is
605 // limited. Since this is only used to report metrics, which are known to
606 // already be quite flawed, and the feature is meant to be temporary (either
607 // shipped or abandoned), don't handle this corner case (which should only
608 // happen for the initial partition, which is tiny anyway).
609 if (total_committed_bytes >= total_active_bytes) {
610 wasted = total_committed_bytes - total_active_bytes;
611 }
Thiabaud Engelbrechtff1e1072021-11-13 01:49:41612 size_t fragmentation =
613 total_committed_bytes == 0 ? 0 : 100 * wasted / total_committed_bytes;
614
ssid9becc202022-03-25 05:06:20615 allocator_dump->AddScalar(MemoryAllocatorDump::kNameSize,
616 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02617 memory_stats->total_resident_bytes);
ssid9becc202022-03-25 05:06:20618 allocator_dump->AddScalar("allocated_objects_size",
619 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02620 memory_stats->total_active_bytes);
Keishi Hattorie1464c32022-04-18 19:27:21621 allocator_dump->AddScalar("allocated_objects_count", "count",
622 memory_stats->total_active_count);
ssid9becc202022-03-25 05:06:20623 allocator_dump->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02624 memory_stats->total_mmapped_bytes);
ssid9becc202022-03-25 05:06:20625 allocator_dump->AddScalar("virtual_committed_size",
626 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02627 memory_stats->total_committed_bytes);
ssid9becc202022-03-25 05:06:20628 allocator_dump->AddScalar("max_committed_size",
629 MemoryAllocatorDump::kUnitsBytes,
Thiabaud Engelbrechtd190ee982021-08-11 16:21:27630 memory_stats->max_committed_bytes);
ssid9becc202022-03-25 05:06:20631 allocator_dump->AddScalar("allocated_size", MemoryAllocatorDump::kUnitsBytes,
Thiabaud Engelbrechtd190ee982021-08-11 16:21:27632 memory_stats->total_allocated_bytes);
ssid9becc202022-03-25 05:06:20633 allocator_dump->AddScalar("max_allocated_size",
634 MemoryAllocatorDump::kUnitsBytes,
Thiabaud Engelbrechtd190ee982021-08-11 16:21:27635 memory_stats->max_allocated_bytes);
ssid9becc202022-03-25 05:06:20636 allocator_dump->AddScalar("decommittable_size",
637 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02638 memory_stats->total_decommittable_bytes);
ssid9becc202022-03-25 05:06:20639 allocator_dump->AddScalar("discardable_size",
640 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02641 memory_stats->total_discardable_bytes);
Arthur Sonzogni62e877a2024-04-30 16:09:43642#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
ssid9becc202022-03-25 05:06:20643 allocator_dump->AddScalar("brp_quarantined_size",
644 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattoric713e722021-09-23 03:09:59645 memory_stats->total_brp_quarantined_bytes);
646 allocator_dump->AddScalar("brp_quarantined_count", "count",
647 memory_stats->total_brp_quarantined_count);
Arthur Sonzogni62e877a2024-04-30 16:09:43648#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
Benoit Lizecbd948622021-09-17 09:23:55649 allocator_dump->AddScalar("syscall_count", "count",
650 memory_stats->syscall_count);
651 allocator_dump->AddScalar("syscall_total_time_ms", "ms",
652 memory_stats->syscall_total_time_ns / 1e6);
Thiabaud Engelbrechtff1e1072021-11-13 01:49:41653 allocator_dump->AddScalar("fragmentation", "percent", fragmentation);
ssid9becc202022-03-25 05:06:20654 allocator_dump->AddScalar("wasted", MemoryAllocatorDump::kUnitsBytes, wasted);
Benoit Lizecbd948622021-09-17 09:23:55655
Keishi Hattori3fa56dd2021-04-15 09:33:02656 if (memory_stats->has_thread_cache) {
657 const auto& thread_cache_stats = memory_stats->current_thread_cache_stats;
658 auto* thread_cache_dump = memory_dump_->CreateAllocatorDump(
659 dump_name + "/thread_cache/main_thread");
660 ReportPartitionAllocThreadCacheStats(memory_dump_, thread_cache_dump,
661 thread_cache_stats, ".MainThread",
662 detailed_);
663
664 const auto& all_thread_caches_stats = memory_stats->all_thread_caches_stats;
665 auto* all_thread_caches_dump =
666 memory_dump_->CreateAllocatorDump(dump_name + "/thread_cache");
667 ReportPartitionAllocThreadCacheStats(memory_dump_, all_thread_caches_dump,
668 all_thread_caches_stats, "",
669 detailed_);
670 }
miktf85547d2024-03-13 09:06:20671
672 if (memory_stats->has_scheduler_loop_quarantine) {
673 MemoryAllocatorDump* quarantine_dump_total =
674 memory_dump_->CreateAllocatorDump(dump_name +
675 "/scheduler_loop_quarantine");
676 ReportPartitionAllocLightweightQuarantineStats(
677 quarantine_dump_total,
678 memory_stats->scheduler_loop_quarantine_stats_total);
679 }
Keishi Hattori3fa56dd2021-04-15 09:33:02680}
681
682void MemoryDumpPartitionStatsDumper::PartitionsDumpBucketStats(
683 const char* partition_name,
Kalvin Lee01b3850d2022-06-15 22:41:55684 const partition_alloc::PartitionBucketMemoryStats* memory_stats) {
Keishi Hattori3fa56dd2021-04-15 09:33:02685 DCHECK(memory_stats->is_valid);
686 std::string dump_name = GetPartitionDumpName(root_name_, partition_name);
687 if (memory_stats->is_direct_map) {
688 dump_name.append(base::StringPrintf("/buckets/directMap_%" PRIu64, ++uid_));
689 } else {
Benoit Lize4c0734c2021-09-10 20:14:08690 // Normal buckets go up to ~1MiB, 7 digits.
691 dump_name.append(base::StringPrintf("/buckets/bucket_%07" PRIu32,
Keishi Hattori3fa56dd2021-04-15 09:33:02692 memory_stats->bucket_slot_size));
693 }
694
695 MemoryAllocatorDump* allocator_dump =
696 memory_dump_->CreateAllocatorDump(dump_name);
ssid9becc202022-03-25 05:06:20697 allocator_dump->AddScalar(MemoryAllocatorDump::kNameSize,
698 MemoryAllocatorDump::kUnitsBytes,
699 memory_stats->resident_bytes);
700 allocator_dump->AddScalar("allocated_objects_size",
701 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02702 memory_stats->active_bytes);
ssid9becc202022-03-25 05:06:20703 allocator_dump->AddScalar("slot_size", MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02704 memory_stats->bucket_slot_size);
ssid9becc202022-03-25 05:06:20705 allocator_dump->AddScalar("decommittable_size",
706 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02707 memory_stats->decommittable_bytes);
ssid9becc202022-03-25 05:06:20708 allocator_dump->AddScalar("discardable_size",
709 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02710 memory_stats->discardable_bytes);
711 // TODO(bartekn): Rename the scalar names.
ssid9becc202022-03-25 05:06:20712 allocator_dump->AddScalar("total_slot_span_size",
713 MemoryAllocatorDump::kUnitsBytes,
Keishi Hattori3fa56dd2021-04-15 09:33:02714 memory_stats->allocated_slot_span_size);
ssid9becc202022-03-25 05:06:20715 allocator_dump->AddScalar("active_slot_spans",
716 MemoryAllocatorDump::kUnitsObjects,
Keishi Hattori3fa56dd2021-04-15 09:33:02717 memory_stats->num_active_slot_spans);
ssid9becc202022-03-25 05:06:20718 allocator_dump->AddScalar("full_slot_spans",
719 MemoryAllocatorDump::kUnitsObjects,
Keishi Hattori3fa56dd2021-04-15 09:33:02720 memory_stats->num_full_slot_spans);
ssid9becc202022-03-25 05:06:20721 allocator_dump->AddScalar("empty_slot_spans",
722 MemoryAllocatorDump::kUnitsObjects,
Keishi Hattori3fa56dd2021-04-15 09:33:02723 memory_stats->num_empty_slot_spans);
ssid9becc202022-03-25 05:06:20724 allocator_dump->AddScalar("decommitted_slot_spans",
725 MemoryAllocatorDump::kUnitsObjects,
Keishi Hattori3fa56dd2021-04-15 09:33:02726 memory_stats->num_decommitted_slot_spans);
727}
Arthur Sonzogni62e877a2024-04-30 16:09:43728#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC)
Benoit Lize097d9ce32020-10-26 12:33:39729
Peter Kasting811504a72025-01-09 03:18:50730} // namespace base::trace_event