graph_impl.h 11 KB

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