1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_MEMORY_TRACKER_SNAPSHOT_PARSER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_MEMORY_TRACKER_SNAPSHOT_PARSER_H_ 19 20 #include "perfetto/ext/trace_processor/importers/memory_tracker/graph_processor.h" 21 #include "protos/perfetto/trace/memory_graph.pbzero.h" 22 #include "src/trace_processor/importers/common/process_tracker.h" 23 #include "src/trace_processor/importers/common/track_tracker.h" 24 #include "src/trace_processor/storage/trace_storage.h" 25 #include "src/trace_processor/types/trace_processor_context.h" 26 27 namespace perfetto { 28 namespace trace_processor { 29 30 class TraceProcessorContext; 31 32 class MemoryTrackerSnapshotParser { 33 public: 34 explicit MemoryTrackerSnapshotParser(TraceProcessorContext* context); 35 void ParseMemoryTrackerSnapshot(int64_t ts, protozero::ConstBytes blob); 36 37 void NotifyEndOfFile(); 38 39 private: 40 using RawMemoryNodeMap = 41 std::map<base::PlatformProcessId, std::unique_ptr<RawProcessMemoryNode>>; 42 using IdNodeMap = 43 std::map<MemoryAllocatorNodeId, tables::MemorySnapshotNodeTable::Id>; 44 using ConstBytes = protozero::ConstBytes; 45 46 class ChildNode { 47 public: ChildNode()48 ChildNode() : table_index_(-1) {} 49 GlobalNodeGraph::Node* node_; 50 std::string path_; 51 uint64_t size_; 52 uint64_t effective_size_; 53 int32_t table_index_; 54 }; 55 56 // Reads the proto-encoded memory snapshot of a process (message 57 // MemoryTrackerSnapshot) in given |blob| in order to get: 58 // - map of RawProcessMemoryNode containers |raw_nodes|. It 59 // is need to generates GlobalNodeGraph via GraphProcessor. 60 // - level of detail of the memory graph |level_of_detail|. 61 void ReadProtoSnapshot(ConstBytes blob, 62 RawMemoryNodeMap& raw_nodes, 63 LevelOfDetail& level_of_detail); 64 65 // Generates GlobalNodeGraph via GraphProcessor for given map |raw_nodes|. 66 std::unique_ptr<GlobalNodeGraph> GenerateGraph(RawMemoryNodeMap& raw_nodes); 67 68 // Fills out MemorySnapshotTable, ProcessMemorySnapshotTable, 69 // MemorySnapshotNodeTable, MemorySnapshotEdgeTable with given 70 // timestamp |ts|, |graph|, |level_of_detail|. 71 void EmitRows(int64_t ts, 72 GlobalNodeGraph& graph, 73 LevelOfDetail level_of_detail); 74 75 // Fills out MemorySnapshotNodeTable for given root node 76 // |root_node_graph| and ProcessMemorySnapshotId |proc_snapshot_row_id|. 77 // Generates map of MemoryAllocatorNodeId and MemorySnapshotNodeTable::Id 78 // |id_node_map| which is used at time of filling out of 79 // MemorySnapshotEdgeTable. 80 void EmitMemorySnapshotNodeRows(GlobalNodeGraph::Node& root_node_graph, 81 ProcessMemorySnapshotId& proc_snapshot_row_id, 82 IdNodeMap& id_node_map); 83 84 // Recursively traverses through list of children of |node| to generate full 85 // |path| to every node in MemorySnapshotNodeTable for given 86 // ProcessMemorySnapshotId |proc_snapshot_row_id|. 87 // Generates map of MemoryAllocatorNodeId and MemorySnapshotNodeTable::Id 88 // |id_node_map| which is used at time of filling out of 89 // MemorySnapshotEdgeTable. 90 void EmitMemorySnapshotNodeRowsRecursively( 91 GlobalNodeGraph::Node& node, 92 const std::string&, 93 std::optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id, 94 ProcessMemorySnapshotId& proc_snapshot_row_id, 95 IdNodeMap& id_node_map); 96 97 // Fills out MemorySnapshotNodeTable for given Node 98 // |node|, |path|, MemorySnapshotNodeTable::Id |parent_node_row_id| and 99 // ProcessMemorySnapshotId |proc_snapshot_row_id|. Generates map of 100 // MemoryAllocatorNodeId and MemorySnapshotNodeTable::Id |id_node_map| which 101 // is used at time of filling out of MemorySnapshotEdgeTable. 102 std::optional<tables::MemorySnapshotNodeTable::Id> EmitNode( 103 const GlobalNodeGraph::Node& node, 104 const std::string& path, 105 std::optional<tables::MemorySnapshotNodeTable::Id> parent_node_row_id, 106 ProcessMemorySnapshotId& proc_snapshot_row_id, 107 IdNodeMap& id_node_map); 108 109 void GenerateGraphFromRawNodesAndEmitRows(); 110 111 TraceProcessorContext* context_; 112 std::array<StringId, 3> level_of_detail_ids_; 113 std::array<StringId, 2> unit_ids_; 114 RawMemoryNodeMap aggregate_raw_nodes_; 115 int64_t last_snapshot_timestamp_; 116 LevelOfDetail last_snapshot_level_of_detail_; 117 }; 118 119 } // namespace trace_processor 120 } // namespace perfetto 121 122 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_MEMORY_TRACKER_SNAPSHOT_PARSER_H_ 123