graph_impl.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  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. #include "components/performance_manager/graph/graph_impl.h"
  5. #include <algorithm>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/callback_helpers.h"
  9. #include "base/check_op.h"
  10. #include "base/containers/flat_map.h"
  11. #include "base/containers/flat_set.h"
  12. #include "base/notreached.h"
  13. #include "base/strings/string_piece.h"
  14. #include "components/performance_manager/graph/frame_node_impl.h"
  15. #include "components/performance_manager/graph/node_base.h"
  16. #include "components/performance_manager/graph/page_node_impl.h"
  17. #include "components/performance_manager/graph/process_node_impl.h"
  18. #include "components/performance_manager/graph/system_node_impl.h"
  19. #include "components/performance_manager/graph/worker_node_impl.h"
  20. #include "components/performance_manager/public/graph/node_data_describer.h"
  21. #include "components/performance_manager/public/graph/node_data_describer_registry.h"
  22. namespace ukm {
  23. class UkmEntryBuilder;
  24. } // namespace ukm
  25. namespace performance_manager {
  26. namespace {
  27. // A unique type ID for this implementation.
  28. const uintptr_t kGraphImplType = reinterpret_cast<uintptr_t>(&kGraphImplType);
  29. template <typename NodeObserverType>
  30. void AddObserverImpl(std::vector<NodeObserverType*>* observers,
  31. NodeObserverType* observer) {
  32. DCHECK(observers);
  33. DCHECK(observer);
  34. auto it = std::find(observers->begin(), observers->end(), observer);
  35. DCHECK(it == observers->end());
  36. observers->push_back(observer);
  37. }
  38. template <typename NodeObserverType>
  39. void RemoveObserverImpl(std::vector<NodeObserverType*>* observers,
  40. NodeObserverType* observer) {
  41. DCHECK(observers);
  42. DCHECK(observer);
  43. // We expect to find the observer in the array.
  44. auto it = std::find(observers->begin(), observers->end(), observer);
  45. DCHECK(it != observers->end());
  46. observers->erase(it);
  47. // There should only have been one copy of the observer.
  48. it = std::find(observers->begin(), observers->end(), observer);
  49. DCHECK(it == observers->end());
  50. }
  51. class NodeDataDescriberRegistryImpl : public NodeDataDescriberRegistry {
  52. public:
  53. ~NodeDataDescriberRegistryImpl() override;
  54. // NodeDataDescriberRegistry impl:
  55. void RegisterDescriber(const NodeDataDescriber* describer,
  56. base::StringPiece name) override;
  57. void UnregisterDescriber(const NodeDataDescriber* describer) override;
  58. base::Value DescribeNodeData(const Node* node) const override;
  59. size_t size() const {
  60. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  61. return describers_.size();
  62. }
  63. private:
  64. template <typename NodeType, typename NodeImplType>
  65. base::Value DescribeNodeImpl(
  66. base::Value (NodeDataDescriber::*DescribeFn)(const NodeType*) const,
  67. const NodeImplType* node) const VALID_CONTEXT_REQUIRED(sequence_checker_);
  68. base::flat_map<const NodeDataDescriber*, std::string> describers_
  69. GUARDED_BY_CONTEXT(sequence_checker_);
  70. SEQUENCE_CHECKER(sequence_checker_);
  71. };
  72. template <typename NodeType, typename NodeImplType>
  73. base::Value NodeDataDescriberRegistryImpl::DescribeNodeImpl(
  74. base::Value (NodeDataDescriber::*Describe)(const NodeType*) const,
  75. const NodeImplType* node) const {
  76. base::Value result(base::Value::Type::DICTIONARY);
  77. for (const auto& name_and_describer : describers_) {
  78. base::Value description = (name_and_describer.first->*Describe)(node);
  79. if (!description.is_none()) {
  80. DCHECK_EQ(nullptr, result.FindDictKey(name_and_describer.second));
  81. result.SetKey(name_and_describer.second, std::move(description));
  82. }
  83. }
  84. return result;
  85. }
  86. NodeDataDescriberRegistryImpl::~NodeDataDescriberRegistryImpl() {
  87. // All describers should have unregistered before the graph is destroyed.
  88. DCHECK(describers_.empty());
  89. }
  90. void NodeDataDescriberRegistryImpl::RegisterDescriber(
  91. const NodeDataDescriber* describer,
  92. base::StringPiece name) {
  93. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  94. #if DCHECK_IS_ON()
  95. for (const auto& kv : describers_) {
  96. DCHECK_NE(kv.second, name) << "Name must be unique";
  97. }
  98. #endif
  99. bool inserted =
  100. describers_.insert(std::make_pair(describer, std::string(name))).second;
  101. DCHECK(inserted);
  102. }
  103. void NodeDataDescriberRegistryImpl::UnregisterDescriber(
  104. const NodeDataDescriber* describer) {
  105. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  106. size_t erased = describers_.erase(describer);
  107. DCHECK_EQ(1u, erased);
  108. }
  109. base::Value NodeDataDescriberRegistryImpl::DescribeNodeData(
  110. const Node* node) const {
  111. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  112. const NodeBase* node_base = NodeBase::FromNode(node);
  113. switch (node_base->type()) {
  114. case NodeTypeEnum::kInvalidType:
  115. NOTREACHED();
  116. return base::Value();
  117. case NodeTypeEnum::kFrame:
  118. return DescribeNodeImpl(&NodeDataDescriber::DescribeFrameNodeData,
  119. FrameNodeImpl::FromNodeBase(node_base));
  120. case NodeTypeEnum::kPage:
  121. return DescribeNodeImpl(&NodeDataDescriber::DescribePageNodeData,
  122. PageNodeImpl::FromNodeBase(node_base));
  123. case NodeTypeEnum::kProcess:
  124. return DescribeNodeImpl(&NodeDataDescriber::DescribeProcessNodeData,
  125. ProcessNodeImpl::FromNodeBase(node_base));
  126. case NodeTypeEnum::kSystem:
  127. return DescribeNodeImpl(&NodeDataDescriber::DescribeSystemNodeData,
  128. SystemNodeImpl::FromNodeBase(node_base));
  129. case NodeTypeEnum::kWorker:
  130. return DescribeNodeImpl(&NodeDataDescriber::DescribeWorkerNodeData,
  131. WorkerNodeImpl::FromNodeBase(node_base));
  132. }
  133. }
  134. } // namespace
  135. GraphImpl::GraphImpl() {
  136. DETACH_FROM_SEQUENCE(sequence_checker_);
  137. }
  138. GraphImpl::~GraphImpl() {
  139. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  140. // All graph registered and owned objects should have been cleaned up.
  141. DCHECK(graph_owned_.empty());
  142. DCHECK(registered_objects_.empty());
  143. // At this point, all typed observers should be empty.
  144. DCHECK(graph_observers_.empty());
  145. DCHECK(frame_node_observers_.empty());
  146. DCHECK(page_node_observers_.empty());
  147. DCHECK(process_node_observers_.empty());
  148. DCHECK(system_node_observers_.empty());
  149. // All process and frame nodes should have been removed already.
  150. DCHECK(processes_by_pid_.empty());
  151. DCHECK(frames_by_id_.empty());
  152. // All nodes should have been removed.
  153. DCHECK(nodes_.empty());
  154. }
  155. void GraphImpl::SetUp() {
  156. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  157. CreateSystemNode();
  158. }
  159. void GraphImpl::TearDown() {
  160. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  161. // Notify graph observers that the graph is being destroyed.
  162. for (auto* observer : graph_observers_)
  163. observer->OnBeforeGraphDestroyed(this);
  164. // Clean up graph owned objects. This causes their TakeFromGraph callbacks to
  165. // be invoked, and ideally they clean up any observers they may have, etc.
  166. graph_owned_.ReleaseObjects(this);
  167. // At this point, all typed observers should be empty.
  168. DCHECK(graph_observers_.empty());
  169. DCHECK(frame_node_observers_.empty());
  170. DCHECK(page_node_observers_.empty());
  171. DCHECK(process_node_observers_.empty());
  172. DCHECK(system_node_observers_.empty());
  173. // Remove the system node from the graph, this should be the only node left.
  174. ReleaseSystemNode();
  175. DCHECK(nodes_.empty());
  176. }
  177. void GraphImpl::AddGraphObserver(GraphObserver* observer) {
  178. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  179. AddObserverImpl(&graph_observers_, observer);
  180. }
  181. void GraphImpl::AddFrameNodeObserver(FrameNodeObserver* observer) {
  182. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  183. AddObserverImpl(&frame_node_observers_, observer);
  184. }
  185. void GraphImpl::AddPageNodeObserver(PageNodeObserver* observer) {
  186. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  187. AddObserverImpl(&page_node_observers_, observer);
  188. }
  189. void GraphImpl::AddProcessNodeObserver(ProcessNodeObserver* observer) {
  190. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  191. AddObserverImpl(&process_node_observers_, observer);
  192. }
  193. void GraphImpl::AddSystemNodeObserver(SystemNodeObserver* observer) {
  194. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  195. AddObserverImpl(&system_node_observers_, observer);
  196. }
  197. void GraphImpl::AddWorkerNodeObserver(WorkerNodeObserver* observer) {
  198. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  199. AddObserverImpl(&worker_node_observers_, observer);
  200. }
  201. void GraphImpl::RemoveGraphObserver(GraphObserver* observer) {
  202. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  203. RemoveObserverImpl(&graph_observers_, observer);
  204. }
  205. void GraphImpl::RemoveFrameNodeObserver(FrameNodeObserver* observer) {
  206. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  207. RemoveObserverImpl(&frame_node_observers_, observer);
  208. }
  209. void GraphImpl::RemovePageNodeObserver(PageNodeObserver* observer) {
  210. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  211. RemoveObserverImpl(&page_node_observers_, observer);
  212. }
  213. void GraphImpl::RemoveProcessNodeObserver(ProcessNodeObserver* observer) {
  214. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  215. RemoveObserverImpl(&process_node_observers_, observer);
  216. }
  217. void GraphImpl::RemoveSystemNodeObserver(SystemNodeObserver* observer) {
  218. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  219. RemoveObserverImpl(&system_node_observers_, observer);
  220. }
  221. void GraphImpl::RemoveWorkerNodeObserver(WorkerNodeObserver* observer) {
  222. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  223. RemoveObserverImpl(&worker_node_observers_, observer);
  224. }
  225. void GraphImpl::PassToGraphImpl(std::unique_ptr<GraphOwned> graph_owned) {
  226. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  227. graph_owned_.PassObject(std::move(graph_owned), this);
  228. }
  229. std::unique_ptr<GraphOwned> GraphImpl::TakeFromGraph(GraphOwned* graph_owned) {
  230. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  231. return graph_owned_.TakeObject(graph_owned, this);
  232. }
  233. void GraphImpl::RegisterObject(GraphRegistered* object) {
  234. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  235. registered_objects_.RegisterObject(object);
  236. }
  237. void GraphImpl::UnregisterObject(GraphRegistered* object) {
  238. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  239. registered_objects_.UnregisterObject(object);
  240. }
  241. const SystemNode* GraphImpl::GetSystemNode() const {
  242. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  243. DCHECK(system_node_.get());
  244. return system_node_.get();
  245. }
  246. std::vector<const ProcessNode*> GraphImpl::GetAllProcessNodes() const {
  247. return GetAllNodesOfType<ProcessNodeImpl, const ProcessNode*>();
  248. }
  249. std::vector<const FrameNode*> GraphImpl::GetAllFrameNodes() const {
  250. return GetAllNodesOfType<FrameNodeImpl, const FrameNode*>();
  251. }
  252. std::vector<const PageNode*> GraphImpl::GetAllPageNodes() const {
  253. return GetAllNodesOfType<PageNodeImpl, const PageNode*>();
  254. }
  255. std::vector<const WorkerNode*> GraphImpl::GetAllWorkerNodes() const {
  256. return GetAllNodesOfType<WorkerNodeImpl, const WorkerNode*>();
  257. }
  258. bool GraphImpl::HasOnlySystemNode() const {
  259. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  260. return nodes_.size() == 1 && *nodes_.begin() == GetSystemNodeImpl();
  261. }
  262. ukm::UkmRecorder* GraphImpl::GetUkmRecorder() const {
  263. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  264. return ukm_recorder();
  265. }
  266. NodeDataDescriberRegistry* GraphImpl::GetNodeDataDescriberRegistry() const {
  267. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  268. if (!describer_registry_)
  269. describer_registry_ = std::make_unique<NodeDataDescriberRegistryImpl>();
  270. return describer_registry_.get();
  271. }
  272. uintptr_t GraphImpl::GetImplType() const {
  273. return kGraphImplType;
  274. }
  275. const void* GraphImpl::GetImpl() const {
  276. return this;
  277. }
  278. #if DCHECK_IS_ON()
  279. bool GraphImpl::IsOnGraphSequence() const {
  280. return sequence_checker_.CalledOnValidSequence();
  281. }
  282. #endif
  283. GraphRegistered* GraphImpl::GetRegisteredObject(uintptr_t type_id) {
  284. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  285. return registered_objects_.GetRegisteredObject(type_id);
  286. }
  287. // static
  288. GraphImpl* GraphImpl::FromGraph(const Graph* graph) {
  289. CHECK_EQ(kGraphImplType, graph->GetImplType());
  290. return reinterpret_cast<GraphImpl*>(const_cast<void*>(graph->GetImpl()));
  291. }
  292. bool GraphImpl::NodeInGraph(const NodeBase* node) {
  293. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  294. const auto& it = nodes_.find(const_cast<NodeBase*>(node));
  295. return it != nodes_.end();
  296. }
  297. ProcessNodeImpl* GraphImpl::GetProcessNodeByPid(base::ProcessId pid) const {
  298. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  299. auto it = processes_by_pid_.find(pid);
  300. if (it == processes_by_pid_.end())
  301. return nullptr;
  302. return it->second;
  303. }
  304. FrameNodeImpl* GraphImpl::GetFrameNodeById(
  305. RenderProcessHostId render_process_id,
  306. int render_frame_id) const {
  307. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  308. auto it =
  309. frames_by_id_.find(ProcessAndFrameId(render_process_id, render_frame_id));
  310. if (it == frames_by_id_.end())
  311. return nullptr;
  312. return it->second;
  313. }
  314. std::vector<ProcessNodeImpl*> GraphImpl::GetAllProcessNodeImpls() const {
  315. return GetAllNodesOfType<ProcessNodeImpl, ProcessNodeImpl*>();
  316. }
  317. std::vector<FrameNodeImpl*> GraphImpl::GetAllFrameNodeImpls() const {
  318. return GetAllNodesOfType<FrameNodeImpl, FrameNodeImpl*>();
  319. }
  320. std::vector<PageNodeImpl*> GraphImpl::GetAllPageNodeImpls() const {
  321. return GetAllNodesOfType<PageNodeImpl, PageNodeImpl*>();
  322. }
  323. std::vector<WorkerNodeImpl*> GraphImpl::GetAllWorkerNodeImpls() const {
  324. return GetAllNodesOfType<WorkerNodeImpl, WorkerNodeImpl*>();
  325. }
  326. size_t GraphImpl::GetNodeAttachedDataCountForTesting(const Node* node,
  327. const void* key) const {
  328. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  329. if (!node && !key)
  330. return node_attached_data_map_.size();
  331. size_t count = 0;
  332. for (auto& node_data : node_attached_data_map_) {
  333. if (node && node_data.first.first != node)
  334. continue;
  335. if (key && node_data.first.second != key)
  336. continue;
  337. ++count;
  338. }
  339. return count;
  340. }
  341. void GraphImpl::AddNewNode(NodeBase* new_node) {
  342. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  343. DCHECK(!node_in_transition_);
  344. // Add the node to the graph.
  345. auto it = nodes_.insert(new_node);
  346. DCHECK(it.second); // Inserted successfully
  347. // Advance the node through its lifecycle until it is active in the graph. See
  348. // NodeBase and NodeState for full details of the lifecycle.
  349. node_in_transition_ = new_node;
  350. node_in_transition_state_ = NodeState::kNotInGraph;
  351. new_node->JoinGraph(this);
  352. node_in_transition_state_ = NodeState::kInitializing;
  353. new_node->OnJoiningGraph();
  354. node_in_transition_state_ = NodeState::kJoiningGraph;
  355. DispatchNodeAddedNotifications(new_node);
  356. node_in_transition_ = nullptr;
  357. node_in_transition_state_ = NodeState::kNotInGraph;
  358. }
  359. void GraphImpl::RemoveNode(NodeBase* node) {
  360. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  361. DCHECK(NodeInGraph(node));
  362. DCHECK_EQ(this, node->graph());
  363. DCHECK(!node_in_transition_);
  364. // Walk the node through the latter half of its lifecycle. See NodeBase and
  365. // NodeState for full details of the lifecycle.
  366. node->OnBeforeLeavingGraph();
  367. node_in_transition_ = node;
  368. node_in_transition_state_ = NodeState::kLeavingGraph;
  369. DispatchNodeRemovedNotifications(node);
  370. RemoveNodeAttachedData(node); // Data added via the public interface.
  371. node->RemoveNodeAttachedData(); // Data added via the private interface.
  372. node->LeaveGraph();
  373. node_in_transition_ = nullptr;
  374. node_in_transition_state_ = NodeState::kNotInGraph;
  375. // Remove the node itself.
  376. size_t erased = nodes_.erase(node);
  377. DCHECK_EQ(1u, erased);
  378. }
  379. size_t GraphImpl::NodeDataDescriberCountForTesting() const {
  380. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  381. if (!describer_registry_)
  382. return 0;
  383. auto* registry = static_cast<const NodeDataDescriberRegistryImpl*>(
  384. describer_registry_.get());
  385. return registry->size();
  386. }
  387. NodeState GraphImpl::GetNodeState(const NodeBase* node) const {
  388. DCHECK_EQ(this, node->graph());
  389. // If this is a transitioning node (being added to or removed from the graph)
  390. // then return the appropriate state.
  391. if (node == node_in_transition_)
  392. return node_in_transition_state_;
  393. // Otherwise, this is a node at steady state.
  394. return NodeState::kActiveInGraph;
  395. }
  396. template <>
  397. const std::vector<FrameNodeObserver*>& GraphImpl::GetObservers() const {
  398. return frame_node_observers_;
  399. }
  400. template <>
  401. const std::vector<PageNodeObserver*>& GraphImpl::GetObservers() const {
  402. return page_node_observers_;
  403. }
  404. template <>
  405. const std::vector<ProcessNodeObserver*>& GraphImpl::GetObservers() const {
  406. return process_node_observers_;
  407. }
  408. template <>
  409. const std::vector<SystemNodeObserver*>& GraphImpl::GetObservers() const {
  410. return system_node_observers_;
  411. }
  412. template <>
  413. const std::vector<WorkerNodeObserver*>& GraphImpl::GetObservers() const {
  414. return worker_node_observers_;
  415. }
  416. GraphImpl::ProcessAndFrameId::ProcessAndFrameId(
  417. RenderProcessHostId render_process_id,
  418. int render_frame_id)
  419. : render_process_id(render_process_id), render_frame_id(render_frame_id) {}
  420. bool GraphImpl::ProcessAndFrameId::operator<(
  421. const ProcessAndFrameId& other) const {
  422. return std::tie(render_process_id, render_frame_id) <
  423. std::tie(other.render_process_id, other.render_frame_id);
  424. }
  425. GraphImpl::ProcessAndFrameId::~ProcessAndFrameId() = default;
  426. GraphImpl::ProcessAndFrameId::ProcessAndFrameId(
  427. const GraphImpl::ProcessAndFrameId& other) = default;
  428. GraphImpl::ProcessAndFrameId& GraphImpl::ProcessAndFrameId::operator=(
  429. const GraphImpl::ProcessAndFrameId& other) = default;
  430. void GraphImpl::DispatchNodeAddedNotifications(NodeBase* node) {
  431. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  432. // This handles the strongly typed observer notifications.
  433. switch (node->type()) {
  434. case NodeTypeEnum::kFrame: {
  435. auto* frame_node = FrameNodeImpl::FromNodeBase(node);
  436. for (auto* observer : frame_node_observers_)
  437. observer->OnFrameNodeAdded(frame_node);
  438. } break;
  439. case NodeTypeEnum::kPage: {
  440. auto* page_node = PageNodeImpl::FromNodeBase(node);
  441. for (auto* observer : page_node_observers_)
  442. observer->OnPageNodeAdded(page_node);
  443. } break;
  444. case NodeTypeEnum::kProcess: {
  445. auto* process_node = ProcessNodeImpl::FromNodeBase(node);
  446. for (auto* observer : process_node_observers_)
  447. observer->OnProcessNodeAdded(process_node);
  448. } break;
  449. case NodeTypeEnum::kSystem:
  450. break;
  451. case NodeTypeEnum::kWorker: {
  452. auto* worker_node = WorkerNodeImpl::FromNodeBase(node);
  453. for (auto* observer : worker_node_observers_)
  454. observer->OnWorkerNodeAdded(worker_node);
  455. } break;
  456. case NodeTypeEnum::kInvalidType: {
  457. NOTREACHED();
  458. } break;
  459. }
  460. }
  461. void GraphImpl::DispatchNodeRemovedNotifications(NodeBase* node) {
  462. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  463. switch (node->type()) {
  464. case NodeTypeEnum::kFrame: {
  465. auto* frame_node = FrameNodeImpl::FromNodeBase(node);
  466. for (auto* observer : frame_node_observers_)
  467. observer->OnBeforeFrameNodeRemoved(frame_node);
  468. } break;
  469. case NodeTypeEnum::kPage: {
  470. auto* page_node = PageNodeImpl::FromNodeBase(node);
  471. for (auto* observer : page_node_observers_)
  472. observer->OnBeforePageNodeRemoved(page_node);
  473. } break;
  474. case NodeTypeEnum::kProcess: {
  475. auto* process_node = ProcessNodeImpl::FromNodeBase(node);
  476. for (auto* observer : process_node_observers_)
  477. observer->OnBeforeProcessNodeRemoved(process_node);
  478. } break;
  479. case NodeTypeEnum::kSystem:
  480. break;
  481. case NodeTypeEnum::kWorker: {
  482. auto* worker_node = WorkerNodeImpl::FromNodeBase(node);
  483. for (auto* observer : worker_node_observers_)
  484. observer->OnBeforeWorkerNodeRemoved(worker_node);
  485. } break;
  486. case NodeTypeEnum::kInvalidType: {
  487. NOTREACHED();
  488. } break;
  489. }
  490. }
  491. void GraphImpl::RemoveNodeAttachedData(NodeBase* node) {
  492. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  493. const Node* public_node = node->ToNode();
  494. auto lower =
  495. node_attached_data_map_.lower_bound(std::make_pair(public_node, nullptr));
  496. auto upper = node_attached_data_map_.lower_bound(
  497. std::make_pair(public_node + 1, nullptr));
  498. node_attached_data_map_.erase(lower, upper);
  499. }
  500. int64_t GraphImpl::GetNextNodeSerializationId() {
  501. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  502. return ++current_node_serialization_id_;
  503. }
  504. void GraphImpl::BeforeProcessPidChange(ProcessNodeImpl* process,
  505. base::ProcessId new_pid) {
  506. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  507. // On Windows, PIDs are aggressively reused, and because not all process
  508. // creation/death notifications are synchronized, it's possible for more than
  509. // one process node to have the same PID. To handle this, the second and
  510. // subsequent registration override earlier registrations, while
  511. // unregistration will only unregister the current holder of the PID.
  512. if (process->process_id() != base::kNullProcessId) {
  513. auto it = processes_by_pid_.find(process->process_id());
  514. if (it != processes_by_pid_.end() && it->second == process)
  515. processes_by_pid_.erase(it);
  516. }
  517. if (new_pid != base::kNullProcessId)
  518. processes_by_pid_[new_pid] = process;
  519. }
  520. void GraphImpl::RegisterFrameNodeForId(RenderProcessHostId render_process_id,
  521. int render_frame_id,
  522. FrameNodeImpl* frame_node) {
  523. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  524. auto insert_result = frames_by_id_.insert(
  525. {ProcessAndFrameId(render_process_id, render_frame_id), frame_node});
  526. DCHECK(insert_result.second);
  527. }
  528. void GraphImpl::UnregisterFrameNodeForId(RenderProcessHostId render_process_id,
  529. int render_frame_id,
  530. FrameNodeImpl* frame_node) {
  531. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  532. const ProcessAndFrameId process_and_frame_id(render_process_id,
  533. render_frame_id);
  534. DCHECK_EQ(frames_by_id_.find(process_and_frame_id)->second, frame_node);
  535. frames_by_id_.erase(process_and_frame_id);
  536. }
  537. template <typename NodeType, typename ReturnNodeType>
  538. std::vector<ReturnNodeType> GraphImpl::GetAllNodesOfType() const {
  539. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  540. const auto type = NodeType::Type();
  541. std::vector<ReturnNodeType> ret;
  542. for (auto* node : nodes_) {
  543. if (node->type() == type)
  544. ret.push_back(NodeType::FromNodeBase(node));
  545. }
  546. return ret;
  547. }
  548. void GraphImpl::CreateSystemNode() {
  549. DCHECK(!system_node_);
  550. // Create the singleton system node instance. Ownership is taken by the
  551. // graph.
  552. system_node_ = std::make_unique<SystemNodeImpl>();
  553. AddNewNode(system_node_.get());
  554. }
  555. void GraphImpl::ReleaseSystemNode() {
  556. if (!system_node_.get())
  557. return;
  558. RemoveNode(system_node_.get());
  559. system_node_.reset();
  560. }
  561. } // namespace performance_manager