summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc125
1 files changed, 95 insertions, 30 deletions
diff --git a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
index dd1edb88b0d..e31f7721321 100644
--- a/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.cc
@@ -5,8 +5,13 @@
#include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h"
#include <inttypes.h>
+#include <ios>
+#include <sstream>
+#include <string>
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_manager.h"
#include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h"
#include "v8/include/cppgc/heap-statistics.h"
@@ -24,6 +29,27 @@ constexpr const char* HeapTypeString(
}
}
+void RecordType(
+ std::vector<cppgc::HeapStatistics::ObjectStatsEntry>& global_object_stats,
+ const cppgc::HeapStatistics::ObjectStatsEntry& local_object_stats,
+ size_t entry_index) {
+ global_object_stats[entry_index].allocated_bytes +=
+ local_object_stats.allocated_bytes;
+ global_object_stats[entry_index].object_count +=
+ local_object_stats.object_count;
+}
+
+// Use the id to generate a unique name as different types may provide the same
+// string as typename. This happens in component builds when cppgc creates
+// different internal types for the same C++ class when it is instantiated from
+// different libraries.
+std::string GetUniqueName(std::string name, size_t id) {
+ std::stringstream stream;
+ // Convert the id to hex to avoid it reading like an object count.
+ stream << name << " (0x" << std::hex << id << ")";
+ return stream.str();
+}
+
} // namespace
BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider(
@@ -33,7 +59,7 @@ BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider(
: thread_state_(thread_state),
heap_type_(heap_type),
dump_base_name_(
- "blink_gc/" + std::string(HeapTypeString(heap_type_)) + "/heap" +
+ "blink_gc/" + std::string(HeapTypeString(heap_type_)) +
(heap_type_ == HeapType::kBlinkWorkerThread
? "/" + base::StringPrintf(
"worker_0x%" PRIXPTR,
@@ -60,10 +86,11 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
::cppgc::HeapStatistics stats =
ThreadState::Current()->cpp_heap().CollectStatistics(detail_level);
- auto* heap_dump = process_memory_dump->CreateAllocatorDump(dump_base_name_);
+ auto* heap_dump =
+ process_memory_dump->CreateAllocatorDump(dump_base_name_ + "/heap");
heap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- stats.physical_size_bytes);
+ stats.resident_size_bytes);
heap_dump->AddScalar("allocated_objects_size",
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
stats.used_size_bytes);
@@ -72,16 +99,19 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
return true;
}
- // Detailed statistics.
+ // Aggregate global object stats from per page statistics.
+ std::vector<cppgc::HeapStatistics::ObjectStatsEntry> global_object_stats;
+ global_object_stats.resize(stats.type_names.size());
+
+ // Detailed statistics follow.
for (const ::cppgc::HeapStatistics::SpaceStatistics& space_stats :
stats.space_stats) {
- std::string arena_dump_name = dump_base_name_ + "/" + space_stats.name;
- auto* arena_dump =
- process_memory_dump->CreateAllocatorDump(arena_dump_name);
- arena_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ auto* space_dump = process_memory_dump->CreateAllocatorDump(
+ heap_dump->absolute_name() + "/" + space_stats.name);
+ space_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- space_stats.physical_size_bytes);
- arena_dump->AddScalar("allocated_objects_size",
+ space_stats.resident_size_bytes);
+ space_dump->AddScalar("allocated_objects_size",
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
space_stats.used_size_bytes);
@@ -89,19 +119,42 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
for (const ::cppgc::HeapStatistics::PageStatistics& page_stats :
space_stats.page_stats) {
auto* page_dump = process_memory_dump->CreateAllocatorDump(
- arena_dump_name + "/pages/page_" +
+ space_dump->absolute_name() + "/pages/page_" +
base::NumberToString(page_count++));
+ page_dump->AddScalar("committed_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ page_stats.committed_size_bytes);
page_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- page_stats.physical_size_bytes);
+ page_stats.resident_size_bytes);
page_dump->AddScalar("allocated_objects_size",
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
page_stats.used_size_bytes);
+
+ const auto& object_stats = page_stats.object_statistics;
+ for (size_t i = 0; i < object_stats.size(); i++) {
+ if (!object_stats[i].object_count)
+ continue;
+
+ auto* page_class_dump = process_memory_dump->CreateAllocatorDump(
+ page_dump->absolute_name() + "/types/" +
+ GetUniqueName(stats.type_names[i], i));
+ page_class_dump->AddScalar(
+ base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ object_stats[i].object_count);
+ page_class_dump->AddScalar(
+ "allocated_objects_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ object_stats[i].allocated_bytes);
+
+ RecordType(global_object_stats, object_stats[i], i);
+ }
}
const ::cppgc::HeapStatistics::FreeListStatistics& free_list_stats =
space_stats.free_list_stats;
- for (wtf_size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) {
+ for (size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) {
constexpr size_t kDigits = 8;
std::string original_bucket_size =
base::NumberToString(free_list_stats.bucket_size[i]);
@@ -109,28 +162,40 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump(
std::string(kDigits - original_bucket_size.length(), '0') +
original_bucket_size;
auto* free_list_bucket_dump = process_memory_dump->CreateAllocatorDump(
- arena_dump_name + "/freelist/bucket_" + padded_bucket_size);
+ space_dump->absolute_name() + "/freelist/bucket_" +
+ padded_bucket_size);
free_list_bucket_dump->AddScalar(
- "free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ "free_slot_count",
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ free_list_stats.free_count[i]);
+ free_list_bucket_dump->AddScalar(
+ "free_usable_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
free_list_stats.free_size[i]);
}
+ }
- const ::cppgc::HeapStatistics::ObjectStatistics& object_stats =
- space_stats.object_stats;
- for (wtf_size_t i = 1; i < object_stats.num_types; i++) {
- if (object_stats.type_name[i].empty())
- continue;
-
- auto* class_dump = process_memory_dump->CreateAllocatorDump(
- arena_dump_name + "/classes/" + object_stats.type_name[i]);
- class_dump->AddScalar(
- "object_count", base::trace_event::MemoryAllocatorDump::kUnitsObjects,
- object_stats.type_count[i]);
- class_dump->AddScalar("object_size",
- base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- object_stats.type_bytes[i]);
- }
+ // Populate "allocated_objects" and "blink_objects/blink_gc" dumps.
+ const auto* allocated_objects_dump = process_memory_dump->CreateAllocatorDump(
+ dump_base_name_ + "/allocated_objects");
+ for (size_t i = 0; i < global_object_stats.size(); i++) {
+ auto* details = process_memory_dump->CreateAllocatorDump(
+ "blink_objects/blink_gc/" + GetUniqueName(stats.type_names[i], i));
+ details->AddScalar("allocated_objects_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ global_object_stats[i].allocated_bytes);
+ details->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ global_object_stats[i].object_count);
+ details->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ global_object_stats[i].allocated_bytes);
+ process_memory_dump->AddSuballocation(
+ details->guid(), dump_base_name_ + "/allocated_objects");
}
+ process_memory_dump->AddOwnershipEdge(allocated_objects_dump->guid(),
+ heap_dump->guid());
+
return true;
}