1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_GRAPH_IMPL_H_ 6 #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_GRAPH_IMPL_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 #include <unordered_map> 13 #include <unordered_set> 14 #include <utility> 15 #include <vector> 16 17 #include "base/containers/flat_map.h" 18 #include "base/containers/flat_set.h" 19 #include "base/macros.h" 20 #include "base/process/process_handle.h" 21 #include "base/sequence_checker.h" 22 #include "components/performance_manager/owned_objects.h" 23 #include "components/performance_manager/public/graph/graph.h" 24 #include "components/performance_manager/public/graph/graph_registered.h" 25 #include "components/performance_manager/public/graph/node_attached_data.h" 26 #include "components/performance_manager/public/render_process_host_id.h" 27 #include "components/performance_manager/registered_objects.h" 28 #include "services/metrics/public/cpp/ukm_recorder.h" 29 30 namespace performance_manager { 31 32 class FrameNodeImpl; 33 class Node; 34 class NodeBase; 35 class PageNodeImpl; 36 class ProcessNodeImpl; 37 class SystemNodeImpl; 38 class WorkerNodeImpl; 39 40 // Represents a graph of the nodes representing a single browser. Maintains a 41 // set of nodes that can be retrieved in different ways, some indexed. Keeps 42 // a list of observers that are notified of node addition and removal. 43 class GraphImpl : public Graph { 44 public: 45 // Pure virtual observer interface. Derive from this if you want to manually 46 // implement the whole interface, and have the compiler enforce that as new 47 // methods are added. 48 using Observer = GraphObserver; 49 50 using NodeSet = std::unordered_set<NodeBase*>; 51 52 GraphImpl(); 53 ~GraphImpl() override; 54 55 // Tear down the graph to prepare for deletion. 56 void TearDown(); 57 58 // Graph implementation: 59 void AddGraphObserver(GraphObserver* observer) override; 60 void AddFrameNodeObserver(FrameNodeObserver* observer) override; 61 void AddPageNodeObserver(PageNodeObserver* observer) override; 62 void AddProcessNodeObserver(ProcessNodeObserver* observer) override; 63 void AddSystemNodeObserver(SystemNodeObserver* observer) override; 64 void AddWorkerNodeObserver(WorkerNodeObserver* observer) override; 65 void RemoveGraphObserver(GraphObserver* observer) override; 66 void RemoveFrameNodeObserver(FrameNodeObserver* observer) override; 67 void RemovePageNodeObserver(PageNodeObserver* observer) override; 68 void RemoveProcessNodeObserver(ProcessNodeObserver* observer) override; 69 void RemoveSystemNodeObserver(SystemNodeObserver* observer) override; 70 void RemoveWorkerNodeObserver(WorkerNodeObserver* observer) override; 71 void PassToGraphImpl(std::unique_ptr<GraphOwned> graph_owned) override; 72 std::unique_ptr<GraphOwned> TakeFromGraph(GraphOwned* graph_owned) override; 73 void RegisterObject(GraphRegistered* object) override; 74 void UnregisterObject(GraphRegistered* object) override; 75 const SystemNode* FindOrCreateSystemNode() override; 76 std::vector<const ProcessNode*> GetAllProcessNodes() const override; 77 std::vector<const FrameNode*> GetAllFrameNodes() const override; 78 std::vector<const PageNode*> GetAllPageNodes() const override; 79 std::vector<const WorkerNode*> GetAllWorkerNodes() const override; 80 bool IsEmpty() const override; 81 ukm::UkmRecorder* GetUkmRecorder() const override; 82 NodeDataDescriberRegistry* GetNodeDataDescriberRegistry() const override; 83 uintptr_t GetImplType() const override; 84 const void* GetImpl() const override; 85 #if DCHECK_IS_ON() 86 bool IsOnGraphSequence() const override; 87 #endif 88 GraphRegistered* GetRegisteredObject(uintptr_t type_id) override; 89 90 // Helper function for safely downcasting to the implementation. This also 91 // casts away constness. This will CHECK on an invalid cast. 92 static GraphImpl* FromGraph(const Graph* graph); 93 set_ukm_recorder(ukm::UkmRecorder * ukm_recorder)94 void set_ukm_recorder(ukm::UkmRecorder* ukm_recorder) { 95 ukm_recorder_ = ukm_recorder; 96 } ukm_recorder()97 ukm::UkmRecorder* ukm_recorder() const { return ukm_recorder_; } 98 99 SystemNodeImpl* FindOrCreateSystemNodeImpl(); 100 std::vector<ProcessNodeImpl*> GetAllProcessNodeImpls() const; 101 std::vector<FrameNodeImpl*> GetAllFrameNodeImpls() const; 102 std::vector<PageNodeImpl*> GetAllPageNodeImpls() const; 103 std::vector<WorkerNodeImpl*> GetAllWorkerNodeImpls() const; nodes()104 const NodeSet& nodes() { return nodes_; } 105 106 // Retrieves the process node with PID |pid|, if any. 107 ProcessNodeImpl* GetProcessNodeByPid(base::ProcessId pid) const; 108 109 // Retrieves the frame node with the routing ids of the process and the frame. 110 FrameNodeImpl* GetFrameNodeById(RenderProcessHostId render_process_id, 111 int render_frame_id) const; 112 113 // Returns true if |node| is in this graph. 114 bool NodeInGraph(const NodeBase* node); 115 116 // Management functions for node owners, any node added to the graph must be 117 // removed from the graph before it's deleted. 118 void AddNewNode(NodeBase* new_node); 119 void RemoveNode(NodeBase* node); 120 121 // A |key| of nullptr counts all instances associated with the |node|. A 122 // |node| of null counts all instances associated with the |key|. If both are 123 // null then the entire map size is provided. 124 size_t GetNodeAttachedDataCountForTesting(const Node* node, 125 const void* key) const; 126 127 // Allows explicitly invoking SystemNode destruction for testing. ReleaseSystemNodeForTesting()128 void ReleaseSystemNodeForTesting() { ReleaseSystemNode(); } 129 130 // Returns the number of objects in the |graph_owned_| map, for testing. GraphOwnedCountForTesting()131 size_t GraphOwnedCountForTesting() const { return graph_owned_.size(); } 132 133 protected: 134 friend class NodeBase; 135 136 // Provides access to per-node-class typed observers. Exposed to nodes via 137 // TypedNodeBase. 138 template <typename Observer> 139 const std::vector<Observer*>& GetObservers() const; 140 141 private: 142 struct ProcessAndFrameId { 143 ProcessAndFrameId(RenderProcessHostId render_process_id, 144 int render_frame_id); 145 ~ProcessAndFrameId(); 146 147 ProcessAndFrameId(const ProcessAndFrameId& other); 148 ProcessAndFrameId& operator=(const ProcessAndFrameId& other); 149 150 bool operator<(const ProcessAndFrameId& other) const; 151 RenderProcessHostId render_process_id; 152 int render_frame_id; 153 }; 154 155 using ProcessByPidMap = std::map<base::ProcessId, ProcessNodeImpl*>; 156 using FrameById = std::map<ProcessAndFrameId, FrameNodeImpl*>; 157 158 void OnNodeAdded(NodeBase* node); 159 void OnBeforeNodeRemoved(NodeBase* node); 160 161 // Returns a new serialization ID. 162 friend class NodeBase; 163 int64_t GetNextNodeSerializationId(); 164 165 // Process PID map for use by ProcessNodeImpl. 166 friend class ProcessNodeImpl; 167 void BeforeProcessPidChange(ProcessNodeImpl* process, 168 base::ProcessId new_pid); 169 170 // Frame id map for use by FrameNodeImpl. 171 friend class FrameNodeImpl; 172 void RegisterFrameNodeForId(RenderProcessHostId render_process_id, 173 int render_frame_id, 174 FrameNodeImpl* frame_node); 175 void UnregisterFrameNodeForId(RenderProcessHostId render_process_id, 176 int render_frame_id, 177 FrameNodeImpl* frame_node); 178 179 template <typename NodeType, typename ReturnNodeType> 180 std::vector<ReturnNodeType> GetAllNodesOfType() const; 181 182 void ReleaseSystemNode(); 183 184 std::unique_ptr<SystemNodeImpl> system_node_; 185 NodeSet nodes_; 186 ProcessByPidMap processes_by_pid_; 187 FrameById frames_by_id_; 188 ukm::UkmRecorder* ukm_recorder_ = nullptr; 189 190 // Typed observers. 191 // TODO(chrisha): We should wrap these containers in something that catches 192 // invalid reentrant usage in DCHECK builds. 193 std::vector<GraphObserver*> graph_observers_; 194 std::vector<FrameNodeObserver*> frame_node_observers_; 195 std::vector<PageNodeObserver*> page_node_observers_; 196 std::vector<ProcessNodeObserver*> process_node_observers_; 197 std::vector<SystemNodeObserver*> system_node_observers_; 198 std::vector<WorkerNodeObserver*> worker_node_observers_; 199 200 // Graph-owned objects. For now we only expect O(10) clients, hence the 201 // flat_map. 202 OwnedObjects<GraphOwned, 203 /* CallbackArgType = */ Graph*, 204 &GraphOwned::OnPassedToGraph, 205 &GraphOwned::OnTakenFromGraph> 206 graph_owned_; 207 208 // Allocated on first use. 209 mutable std::unique_ptr<NodeDataDescriberRegistry> describer_registry_; 210 211 // User data storage for the graph. 212 friend class NodeAttachedDataMapHelper; 213 using NodeAttachedDataKey = std::pair<const Node*, const void*>; 214 using NodeAttachedDataMap = 215 std::map<NodeAttachedDataKey, std::unique_ptr<NodeAttachedData>>; 216 NodeAttachedDataMap node_attached_data_map_; 217 218 // Storage for GraphRegistered objects. 219 RegisteredObjects<GraphRegistered> registered_objects_; 220 221 // The most recently assigned serialization ID. 222 int64_t current_node_serialization_id_ = 0u; 223 224 SEQUENCE_CHECKER(sequence_checker_); 225 DISALLOW_COPY_AND_ASSIGN(GraphImpl); 226 }; 227 228 } // namespace performance_manager 229 230 #endif // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_GRAPH_IMPL_H_ 231