File: process_node_impl.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (281 lines) | stat: -rw-r--r-- 11,886 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PROCESS_NODE_IMPL_H_
#define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PROCESS_NODE_IMPL_H_

#include <optional>
#include <string>
#include <variant>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
#include "base/time/time.h"
#include "base/types/pass_key.h"
#include "components/performance_manager/decorators/process_priority_aggregator_data.h"
#include "components/performance_manager/freezing/frozen_data.h"
#include "components/performance_manager/graph/node_attached_data_storage.h"
#include "components/performance_manager/graph/node_base.h"
#include "components/performance_manager/graph/node_inline_data.h"
#include "components/performance_manager/graph/properties.h"
#include "components/performance_manager/public/browser_child_process_host_proxy.h"
#include "components/performance_manager/public/graph/process_node.h"
#include "components/performance_manager/public/mojom/coordination_unit.mojom.h"
#include "components/performance_manager/public/mojom/v8_contexts.mojom.h"
#include "components/performance_manager/public/render_process_host_proxy.h"
#include "components/performance_manager/resource_attribution/cpu_measurement_data.h"
#include "components/performance_manager/scenarios/loading_scenario_data.h"
#include "components/performance_manager/scenarios/performance_scenario_data.h"
#include "content/public/browser/background_tracing_manager.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/perfetto/include/perfetto/tracing/track.h"

namespace performance_manager {

class FrameNodeImpl;
class FrozenFrameAggregator;
class ProcessNodeImpl;
class WorkerNodeImpl;

// Tag used to create a process node for the browser process.
struct BrowserProcessNodeTag {};

// A process node follows the lifetime of a chrome process.
// It may reference zero or one processes at a time, but during its lifetime, it
// may reference more than one process. This can happen if the associated
// renderer crashes, and an associated frame is then reloaded or re-navigated.
// The state of the process node goes through:
// 1. Created, no PID.
// 2. Process started, have PID - in the case where the associated render
//    process fails to start, this state may not occur.
// 3. Process died or failed to start, have exit status.
// 4. Back to 2.
class ProcessNodeImpl
    : public PublicNodeImpl<ProcessNodeImpl, ProcessNode>,
      public TypedNodeBase<ProcessNodeImpl, ProcessNode, ProcessNodeObserver>,
      public mojom::ProcessCoordinationUnit,
      public mojom::ChildProcessCoordinationUnit,
      public SupportsNodeInlineData<
          ProcessPriorityAggregatorData,
          FrozenData,
          PerformanceScenarioData,
          resource_attribution::CPUMeasurementData,
          resource_attribution::SharedCPUTimeResultData,
          LoadingScenarioCounts,
          // Keep this last to avoid merge conflicts.
          NodeAttachedDataStorage> {
 public:
  using PassKey = base::PassKey<ProcessNodeImpl>;

  using TypedNodeBase<ProcessNodeImpl, ProcessNode, ProcessNodeObserver>::
      FromNode;

  // Constructor for the browser process.
  explicit ProcessNodeImpl(BrowserProcessNodeTag tag);

  // Constructor for a renderer process.
  ProcessNodeImpl(RenderProcessHostProxy proxy, base::TaskPriority priority);

  // Constructor for a non-renderer child process.
  ProcessNodeImpl(content::ProcessType process_type,
                  BrowserChildProcessHostProxy proxy);

  ProcessNodeImpl(const ProcessNodeImpl&) = delete;
  ProcessNodeImpl& operator=(const ProcessNodeImpl&) = delete;

  ~ProcessNodeImpl() override;

  void BindRenderProcessCoordinationUnit(
      mojo::PendingReceiver<mojom::ProcessCoordinationUnit> receiver);
  void BindChildProcessCoordinationUnit(
      mojo::PendingReceiver<mojom::ChildProcessCoordinationUnit> receiver);

  // mojom::ProcessCoordinationUnit implementation:
  void SetMainThreadTaskLoadIsLow(bool main_thread_task_load_is_low) override;
  void OnV8ContextCreated(
      mojom::V8ContextDescriptionPtr description,
      mojom::IframeAttributionDataPtr iframe_attribution_data) override;
  void OnV8ContextDetached(
      const blink::V8ContextToken& v8_context_token) override;
  void OnV8ContextDestroyed(
      const blink::V8ContextToken& v8_context_token) override;
  void OnRemoteIframeAttached(
      const blink::LocalFrameToken& parent_frame_token,
      const blink::RemoteFrameToken& remote_frame_token,
      mojom::IframeAttributionDataPtr iframe_attribution_data) override;
  void OnRemoteIframeDetached(
      const blink::LocalFrameToken& parent_frame_token,
      const blink::RemoteFrameToken& remote_frame_token) override;

  // mojom::ChildProcessCoordinationUnit implementation:
  void InitializeChildProcessCoordination(
      uint64_t process_track_id,
      InitializeChildProcessCoordinationCallback callback) override;

  // Partial ProcessNode implementation:
  content::ProcessType GetProcessType() const override;
  base::ProcessId GetProcessId() const override;
  const base::Process& GetProcess() const override;
  resource_attribution::ProcessContext GetResourceContext() const override;
  base::TimeTicks GetLaunchTime() const override;
  std::optional<int32_t> GetExitStatus() const override;
  const std::string& GetMetricsName() const override;
  bool GetMainThreadTaskLoadIsLow() const override;
  uint64_t GetPrivateFootprintKb() const override;
  uint64_t GetResidentSetKb() const override;
  uint64_t GetPrivateSwapKb() const override;
  RenderProcessHostId GetRenderProcessHostId() const override;
  const RenderProcessHostProxy& GetRenderProcessHostProxy() const override;
  const BrowserChildProcessHostProxy& GetBrowserChildProcessHostProxy()
      const override;
  base::TaskPriority GetPriority() const override;
  ContentTypes GetHostedContentTypes() const override;

  // Private implementation properties.
  NodeSetView<FrameNodeImpl*> frame_nodes() const;
  NodeSetView<WorkerNodeImpl*> worker_nodes() const;
  std::optional<perfetto::Track> tracing_track() const;

  void SetProcessExitStatus(int32_t exit_status);
  void SetProcessMetricsName(const std::string& metrics_name);
  void SetProcess(base::Process process, base::TimeTicks launch_time);

  void set_private_footprint_kb(uint64_t private_footprint_kb) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    private_footprint_kb_ = private_footprint_kb;
  }
  void set_resident_set_kb(uint64_t resident_set_kb) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    resident_set_kb_ = resident_set_kb;
  }
  void set_private_swap_kb(uint64_t private_swap_kb) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    private_swap_kb_ = private_swap_kb;
  }

  // Add |frame_node| to this process.
  void AddFrame(FrameNodeImpl* frame_node);
  // Removes |frame_node| from the set of frames hosted by this process. Invoked
  // when the frame is removed from the graph.
  void RemoveFrame(FrameNodeImpl* frame_node);

  // Add |worker_node| to this process.
  void AddWorker(WorkerNodeImpl* worker_node);
  // Removes |worker_node| from the set of workers hosted by this process.
  // Invoked when the worker is removed from the graph.
  void RemoveWorker(WorkerNodeImpl* worker_node);

  void set_priority(base::TaskPriority priority);

  // Adds a new type of hosted content to the |hosted_content_types| bit field.
  void add_hosted_content_type(ContentType content_type);

  void OnAllFramesInProcessFrozen(base::PassKey<FrozenFrameAggregator>) {
    OnAllFramesInProcessFrozen();
  }

  void OnAllFramesInProcessFrozenForTesting() { OnAllFramesInProcessFrozen(); }

  base::WeakPtr<ProcessNodeImpl> GetWeakPtr();

  static PassKey CreatePassKeyForTesting() { return PassKey(); }

 protected:
  void SetProcessImpl(base::Process process,
                      base::ProcessId process_id,
                      base::TimeTicks launch_time);

 private:
  friend class ProcessMetricsDecoratorAccess;

  using AnyChildProcessHostProxy =
      std::variant<RenderProcessHostProxy, BrowserChildProcessHostProxy>;

  // Shared constructor for all process types.
  ProcessNodeImpl(content::ProcessType process_type,
                  AnyChildProcessHostProxy proxy,
                  base::TaskPriority priority);

  // Rest of ProcessNode implementation. These are private so that users of the
  // impl use the private getters rather than the public interface.
  NodeSetView<const FrameNode*> GetFrameNodes() const override;
  NodeSetView<const WorkerNode*> GetWorkerNodes() const override;

  void OnAllFramesInProcessFrozen();

  // NodeBase:
  void OnInitializingProperties() override;
  void OnUninitializingEdges() override;
  void CleanUpNodeState() override;

  // Receiver for renderer-only messages.
  mojo::Receiver<mojom::ProcessCoordinationUnit> render_process_receiver_
      GUARDED_BY_CONTEXT(sequence_checker_){this};

  // Receiver for messages from all child processes.
  mojo::Receiver<mojom::ChildProcessCoordinationUnit> child_process_receiver_
      GUARDED_BY_CONTEXT(sequence_checker_){this};

  uint64_t private_footprint_kb_ GUARDED_BY_CONTEXT(sequence_checker_) = 0u;
  uint64_t resident_set_kb_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
  uint64_t private_swap_kb_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;

  base::ProcessId process_id_ GUARDED_BY_CONTEXT(sequence_checker_) =
      base::kNullProcessId;
  ObservedProperty::NotifiesAlways<
      base::Process,
      &ProcessNodeObserver::OnProcessLifetimeChange>
      process_ GUARDED_BY_CONTEXT(sequence_checker_);

  base::TimeTicks launch_time_ GUARDED_BY_CONTEXT(sequence_checker_);
  std::optional<int32_t> exit_status_ GUARDED_BY_CONTEXT(sequence_checker_);
  std::string metrics_name_ GUARDED_BY_CONTEXT(sequence_checker_);

  // The type of the process that this node represents.
  const content::ProcessType process_type_;

  // The proxy that allows access to either the RenderProcessHost or the
  // BrowserChildProcessHost associated with this process, if `this` is a
  // process node for a child process (process_type() != PROCESS_TYPE_BROWSER).
  const AnyChildProcessHostProxy child_process_host_proxy_;

  ObservedProperty::NotifiesOnlyOnChanges<
      bool,
      &ProcessNodeObserver::OnMainThreadTaskLoadIsLow>
      main_thread_task_load_is_low_ GUARDED_BY_CONTEXT(sequence_checker_){
          false};

  // Process priority information. This is aggregated from the priority of
  // all workers and frames in a given process by the ProcessPriorityAggregator.
  // Initially high priority until the first execution context it hosts
  // determine the right priority.
  ObservedProperty::NotifiesOnlyOnChangesWithPreviousValue<
      base::TaskPriority,
      base::TaskPriority,
      &ProcessNodeObserver::OnPriorityChanged>
      priority_ GUARDED_BY_CONTEXT(sequence_checker_);

  // A bit field that indicates which type of content this process has hosted,
  // either currently or in the past.
  ContentTypes hosted_content_types_ GUARDED_BY_CONTEXT(sequence_checker_);

  // The Perfetto ProcessTrack for this process.
  std::optional<perfetto::Track> tracing_track_
      GUARDED_BY_CONTEXT(sequence_checker_);

  NodeSet frame_nodes_ GUARDED_BY_CONTEXT(sequence_checker_);

  NodeSet worker_nodes_ GUARDED_BY_CONTEXT(sequence_checker_);

  base::WeakPtrFactory<ProcessNodeImpl> weak_factory_
      GUARDED_BY_CONTEXT(sequence_checker_){this};
};

}  // namespace performance_manager

#endif  // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_PROCESS_NODE_IMPL_H_