Commit 15e52341 authored by Maciej Malinowski's avatar Maciej Malinowski Committed by Commit Bot

Replace GraphProcessor by ChromeGraphProcessor

The ChromeGraphProcessor is a wrapper for Perfetto GraphProcessor
implementation. This class takes care of all required conversions
of the input and output parameters between Chrome and Perfetto types.
This is another step of moving GraphProcessor from Chrome to Perfetto.
See crbug.com/1095982 for more details.

Bug: 1095982
Change-Id: Icdef3a6729e207e9cbb5d7fcb9eb90dfcfe07145
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302697
Commit-Queue: ssid <ssid@chromium.org>
Reviewed-by: default avatarssid <ssid@chromium.org>
Reviewed-by: default avatarEric Seckler <eseckler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806195}
parent 978da1d4
...@@ -17,18 +17,20 @@ ...@@ -17,18 +17,20 @@
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "services/resource_coordinator/memory_instrumentation/aggregate_metrics_processor.h" #include "services/resource_coordinator/memory_instrumentation/aggregate_metrics_processor.h"
#include "services/resource_coordinator/memory_instrumentation/graph_processor.h" #include "services/resource_coordinator/memory_instrumentation/memory_dump_map_converter.h"
#include "services/resource_coordinator/memory_instrumentation/switches.h" #include "services/resource_coordinator/memory_instrumentation/switches.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h" #include "third_party/perfetto/include/perfetto/ext/trace_processor/importers/memory_tracker/graph_processor.h"
#if defined(OS_MAC) #if defined(OS_MAC)
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#endif #endif
using base::trace_event::MemoryAllocatorDump;
using base::trace_event::MemoryDumpLevelOfDetail;
using base::trace_event::TracedValue; using base::trace_event::TracedValue;
using Node = memory_instrumentation::GlobalDumpGraph::Node; using perfetto::trace_processor::GlobalNodeGraph;
using perfetto::trace_processor::LevelOfDetail;
using perfetto::trace_processor::RawMemoryGraphNode;
using Node = perfetto::trace_processor::GlobalNodeGraph::Node;
using perfetto::trace_processor::GraphProcessor;
namespace memory_instrumentation { namespace memory_instrumentation {
...@@ -89,7 +91,7 @@ memory_instrumentation::mojom::OSMemDumpPtr CreatePublicOSDump( ...@@ -89,7 +91,7 @@ memory_instrumentation::mojom::OSMemDumpPtr CreatePublicOSDump(
return os_dump; return os_dump;
} }
void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node, void NodeAsValueIntoRecursively(const GlobalNodeGraph::Node& node,
TracedValue* value, TracedValue* value,
std::vector<base::StringPiece>* path) { std::vector<base::StringPiece>* path) {
// Don't dump the root node. // Don't dump the root node.
...@@ -99,31 +101,31 @@ void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node, ...@@ -99,31 +101,31 @@ void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node,
std::string name = base::JoinString(*path, "/"); std::string name = base::JoinString(*path, "/");
value->BeginDictionaryWithCopiedName(name); value->BeginDictionaryWithCopiedName(name);
if (!node.guid().empty()) if (!node.id().empty())
value->SetString("guid", node.guid().ToString()); value->SetString("id", node.id().ToString());
value->BeginDictionary("attrs"); value->BeginDictionary("attrs");
for (const auto& name_to_entry : node.const_entries()) { for (const auto& name_to_entry : node.const_entries()) {
const auto& entry = name_to_entry.second; const auto& entry = name_to_entry.second;
value->BeginDictionaryWithCopiedName(name_to_entry.first); value->BeginDictionaryWithCopiedName(name_to_entry.first);
switch (entry.type) { switch (entry.type) {
case GlobalDumpGraph::Node::Entry::kUInt64: case GlobalNodeGraph::Node::Entry::kUInt64:
base::SStringPrintf(&string_conversion_buffer, "%" PRIx64, base::SStringPrintf(&string_conversion_buffer, "%" PRIx64,
entry.value_uint64); entry.value_uint64);
value->SetString("type", MemoryAllocatorDump::kTypeScalar); value->SetString("type", RawMemoryGraphNode::kTypeScalar);
value->SetString("value", string_conversion_buffer); value->SetString("value", string_conversion_buffer);
break; break;
case GlobalDumpGraph::Node::Entry::kString: case GlobalNodeGraph::Node::Entry::kString:
value->SetString("type", MemoryAllocatorDump::kTypeString); value->SetString("type", RawMemoryGraphNode::kTypeString);
value->SetString("value", entry.value_string); value->SetString("value", entry.value_string);
break; break;
} }
switch (entry.units) { switch (entry.units) {
case GlobalDumpGraph::Node::Entry::ScalarUnits::kBytes: case GlobalNodeGraph::Node::Entry::ScalarUnits::kBytes:
value->SetString("units", MemoryAllocatorDump::kUnitsBytes); value->SetString("units", RawMemoryGraphNode::kUnitsBytes);
break; break;
case GlobalDumpGraph::Node::Entry::ScalarUnits::kObjects: case GlobalNodeGraph::Node::Entry::ScalarUnits::kObjects:
value->SetString("units", MemoryAllocatorDump::kUnitsObjects); value->SetString("units", RawMemoryGraphNode::kUnitsObjects);
break; break;
} }
value->EndDictionary(); value->EndDictionary();
...@@ -131,7 +133,7 @@ void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node, ...@@ -131,7 +133,7 @@ void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node,
value->EndDictionary(); // "attrs": { ... } value->EndDictionary(); // "attrs": { ... }
if (node.is_weak()) if (node.is_weak())
value->SetInteger("flags", MemoryAllocatorDump::Flags::WEAK); value->SetInteger("flags", RawMemoryGraphNode::Flags::kWeak);
value->EndDictionary(); // "allocator_name/heap_subheap": { ... } value->EndDictionary(); // "allocator_name/heap_subheap": { ... }
} }
...@@ -144,7 +146,7 @@ void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node, ...@@ -144,7 +146,7 @@ void NodeAsValueIntoRecursively(const GlobalDumpGraph::Node& node,
} }
std::unique_ptr<TracedValue> GetChromeDumpTracedValue( std::unique_ptr<TracedValue> GetChromeDumpTracedValue(
const GlobalDumpGraph::Process& process) { const GlobalNodeGraph::Process& process) {
std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>(); std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>();
if (!process.root()->const_children().empty()) { if (!process.root()->const_children().empty()) {
traced_value->BeginDictionary("allocators"); traced_value->BeginDictionary("allocators");
...@@ -156,9 +158,9 @@ std::unique_ptr<TracedValue> GetChromeDumpTracedValue( ...@@ -156,9 +158,9 @@ std::unique_ptr<TracedValue> GetChromeDumpTracedValue(
} }
std::unique_ptr<TracedValue> GetChromeDumpAndGlobalAndEdgesTracedValue( std::unique_ptr<TracedValue> GetChromeDumpAndGlobalAndEdgesTracedValue(
const GlobalDumpGraph::Process& process, const GlobalNodeGraph::Process& process,
const GlobalDumpGraph::Process& global_process, const GlobalNodeGraph::Process& global_process,
const std::forward_list<GlobalDumpGraph::Edge>& edges) { const std::forward_list<GlobalNodeGraph::Edge>& edges) {
std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>(); std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>();
bool suppress_graphs = process.root()->const_children().empty() && bool suppress_graphs = process.root()->const_children().empty() &&
global_process.root()->const_children().empty(); global_process.root()->const_children().empty();
...@@ -174,8 +176,8 @@ std::unique_ptr<TracedValue> GetChromeDumpAndGlobalAndEdgesTracedValue( ...@@ -174,8 +176,8 @@ std::unique_ptr<TracedValue> GetChromeDumpAndGlobalAndEdgesTracedValue(
traced_value->BeginArray("allocators_graph"); traced_value->BeginArray("allocators_graph");
for (const auto& edge : edges) { for (const auto& edge : edges) {
traced_value->BeginDictionary(); traced_value->BeginDictionary();
traced_value->SetString("source", edge.source()->guid().ToString()); traced_value->SetString("source", edge.source()->id().ToString());
traced_value->SetString("target", edge.target()->guid().ToString()); traced_value->SetString("target", edge.target()->id().ToString());
traced_value->SetInteger("importance", edge.priority()); traced_value->SetInteger("importance", edge.priority());
traced_value->EndDictionary(); traced_value->EndDictionary();
} }
...@@ -438,18 +440,26 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request, ...@@ -438,18 +440,26 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request,
#endif #endif
} // for (response : request->responses) } // for (response : request->responses)
MemoryDumpMapConverter converter;
perfetto::trace_processor::GraphProcessor::RawMemoryNodeMap perfettoNodeMap =
converter.Convert(pid_to_pmd);
// Generate the global memory graph from the map of pids to dumps, removing // Generate the global memory graph from the map of pids to dumps, removing
// weak nodes. // weak nodes.
std::unique_ptr<GlobalDumpGraph> global_graph = std::unique_ptr<GlobalNodeGraph> global_graph =
GraphProcessor::CreateMemoryGraph(pid_to_pmd); GraphProcessor::CreateMemoryGraph(perfettoNodeMap);
GraphProcessor::RemoveWeakNodesFromGraph(global_graph.get()); GraphProcessor::RemoveWeakNodesFromGraph(global_graph.get());
// Compute the shared memory footprint for each process from the graph. // Compute the shared memory footprint for each process from the graph.
std::map<base::ProcessId, uint64_t> shared_footprints = auto original =
GraphProcessor::ComputeSharedFootprintFromGraph(*global_graph); GraphProcessor::ComputeSharedFootprintFromGraph(*global_graph);
std::map<base::ProcessId, uint64_t> shared_footprints;
for (const auto& item : original) {
shared_footprints.emplace(static_cast<base::ProcessId>(item.first),
item.second);
}
// Perform the rest of the computation on the graph. // Perform the rest of the computation on the graph.
GraphProcessor::AddOverheadsAndPropogateEntries(global_graph.get()); GraphProcessor::AddOverheadsAndPropagateEntries(global_graph.get());
GraphProcessor::CalculateSizesForGraph(global_graph.get()); GraphProcessor::CalculateSizesForGraph(global_graph.get());
// Build up the global dump by iterating on the |valid| process dumps. // Build up the global dump by iterating on the |valid| process dumps.
...@@ -476,16 +486,16 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request, ...@@ -476,16 +486,16 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request,
if (raw_os_dump) { if (raw_os_dump) {
uint64_t shared_resident_kb = 0; uint64_t shared_resident_kb = 0;
#if defined(OS_MAC) #if defined(OS_MAC)
// The resident, anonymous shared memory for each process is only relevant // The resident, anonymous shared memory for each process is only
// on macOS. // relevant on macOS.
const auto process_graph_it = const auto process_graph_it =
global_graph->process_dump_graphs().find(pid); global_graph->process_node_graphs().find(pid);
if (process_graph_it != global_graph->process_dump_graphs().end()) { if (process_graph_it != global_graph->process_node_graphs().end()) {
const auto& process_graph = process_graph_it->second; const auto& process_graph = process_graph_it->second;
auto* node = process_graph->FindNode("shared_memory"); auto* node = process_graph->FindNode("shared_memory");
if (node) { if (node) {
const auto& entry = const auto& entry =
node->entries()->find(MemoryAllocatorDump::kNameSize); node->entries()->find(RawMemoryGraphNode::kNameSize);
if (entry != node->entries()->end()) if (entry != node->entries()->end())
shared_resident_kb = entry->second.value_uint64 / 1024; shared_resident_kb = entry->second.value_uint64 / 1024;
} }
...@@ -541,7 +551,7 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request, ...@@ -541,7 +551,7 @@ void QueuedRequestDispatcher::Finalize(QueuedRequest* request,
if (request->should_return_summaries() && if (request->should_return_summaries() &&
!request->args.memory_footprint_only) { !request->args.memory_footprint_only) {
const auto& process_graph = const auto& process_graph =
global_graph->process_dump_graphs().find(pid)->second; global_graph->process_node_graphs().find(pid)->second;
for (const std::string& name : request->args.allocator_dump_names) { for (const std::string& name : request->args.allocator_dump_names) {
auto* node = process_graph->FindNode(name); auto* node = process_graph->FindNode(name);
// Silently ignore any missing node in the process graph. // Silently ignore any missing node in the process graph.
...@@ -590,7 +600,7 @@ bool QueuedRequestDispatcher::AddChromeMemoryDumpToTrace( ...@@ -590,7 +600,7 @@ bool QueuedRequestDispatcher::AddChromeMemoryDumpToTrace(
const base::trace_event::MemoryDumpRequestArgs& args, const base::trace_event::MemoryDumpRequestArgs& args,
base::ProcessId pid, base::ProcessId pid,
const base::trace_event::ProcessMemoryDump& raw_chrome_dump, const base::trace_event::ProcessMemoryDump& raw_chrome_dump,
const GlobalDumpGraph& global_graph, const GlobalNodeGraph& global_graph,
const std::map<base::ProcessId, mojom::ProcessType>& pid_to_process_type, const std::map<base::ProcessId, mojom::ProcessType>& pid_to_process_type,
TracingObserver* tracing_observer) { TracingObserver* tracing_observer) {
bool is_chrome_tracing_enabled = bool is_chrome_tracing_enabled =
...@@ -603,8 +613,8 @@ bool QueuedRequestDispatcher::AddChromeMemoryDumpToTrace( ...@@ -603,8 +613,8 @@ bool QueuedRequestDispatcher::AddChromeMemoryDumpToTrace(
if (!tracing_observer->ShouldAddToTrace(args)) if (!tracing_observer->ShouldAddToTrace(args))
return false; return false;
const GlobalDumpGraph::Process& process = const GlobalNodeGraph::Process& process =
*global_graph.process_dump_graphs().find(pid)->second; *global_graph.process_node_graphs().find(pid)->second;
std::unique_ptr<TracedValue> traced_value; std::unique_ptr<TracedValue> traced_value;
if (pid_to_process_type.find(pid)->second == mojom::ProcessType::BROWSER) { if (pid_to_process_type.find(pid)->second == mojom::ProcessType::BROWSER) {
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/trace_event/memory_dump_request_args.h" #include "base/trace_event/memory_dump_request_args.h"
#include "services/resource_coordinator/memory_instrumentation/coordinator_impl.h" #include "services/resource_coordinator/memory_instrumentation/coordinator_impl.h"
#include "services/resource_coordinator/memory_instrumentation/graph.h"
#include "services/resource_coordinator/memory_instrumentation/queued_request.h" #include "services/resource_coordinator/memory_instrumentation/queued_request.h"
#include "third_party/perfetto/include/perfetto/ext/trace_processor/importers/memory_tracker/graph.h"
namespace memory_instrumentation { namespace memory_instrumentation {
...@@ -76,7 +76,7 @@ class QueuedRequestDispatcher { ...@@ -76,7 +76,7 @@ class QueuedRequestDispatcher {
const base::trace_event::MemoryDumpRequestArgs& args, const base::trace_event::MemoryDumpRequestArgs& args,
base::ProcessId pid, base::ProcessId pid,
const base::trace_event::ProcessMemoryDump& raw_chrome_dump, const base::trace_event::ProcessMemoryDump& raw_chrome_dump,
const GlobalDumpGraph& global_graph, const perfetto::trace_processor::GlobalNodeGraph& global_graph,
const std::map<base::ProcessId, mojom::ProcessType>& pid_to_process_type, const std::map<base::ProcessId, mojom::ProcessType>& pid_to_process_type,
TracingObserver* tracing_observer); TracingObserver* tracing_observer);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment