diff options
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.cc | 125 |
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; } |