Coverage Report

Created: 2025-10-31 09:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/deps/v8/include/libplatform/v8-tracing.h
Line
Count
Source
1
// Copyright 2016 the V8 project 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 V8_LIBPLATFORM_V8_TRACING_H_
6
#define V8_LIBPLATFORM_V8_TRACING_H_
7
8
#include <atomic>
9
#include <memory>
10
#include <unordered_set>
11
#include <vector>
12
13
#include "libplatform/libplatform-export.h"
14
#include "v8-platform.h"  // NOLINT(build/include_directory)
15
16
namespace perfetto {
17
namespace trace_processor {
18
class TraceProcessorStorage;
19
}
20
class TracingSession;
21
}
22
23
namespace v8 {
24
25
namespace base {
26
class Mutex;
27
}  // namespace base
28
29
namespace platform {
30
namespace tracing {
31
32
class TraceEventListener;
33
34
const int kTraceMaxNumArgs = 2;
35
36
class V8_PLATFORM_EXPORT TraceObject {
37
 public:
38
  union ArgValue {
39
    uint64_t as_uint;
40
    int64_t as_int;
41
    double as_double;
42
    const void* as_pointer;
43
    const char* as_string;
44
  };
45
46
0
  TraceObject() = default;
47
  ~TraceObject();
48
  void Initialize(
49
      char phase, const uint8_t* category_enabled_flag, const char* name,
50
      const char* scope, uint64_t id, uint64_t bind_id, int num_args,
51
      const char** arg_names, const uint8_t* arg_types,
52
      const uint64_t* arg_values,
53
      std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
54
      unsigned int flags, int64_t timestamp, int64_t cpu_timestamp);
55
  void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp);
56
  void InitializeForTesting(
57
      char phase, const uint8_t* category_enabled_flag, const char* name,
58
      const char* scope, uint64_t id, uint64_t bind_id, int num_args,
59
      const char** arg_names, const uint8_t* arg_types,
60
      const uint64_t* arg_values,
61
      std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
62
      unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
63
      uint64_t duration, uint64_t cpu_duration);
64
65
0
  int pid() const { return pid_; }
66
0
  int tid() const { return tid_; }
67
0
  char phase() const { return phase_; }
68
0
  const uint8_t* category_enabled_flag() const {
69
0
    return category_enabled_flag_;
70
0
  }
71
0
  const char* name() const { return name_; }
72
0
  const char* scope() const { return scope_; }
73
0
  uint64_t id() const { return id_; }
74
0
  uint64_t bind_id() const { return bind_id_; }
75
0
  int num_args() const { return num_args_; }
76
0
  const char** arg_names() { return arg_names_; }
77
0
  uint8_t* arg_types() { return arg_types_; }
78
0
  ArgValue* arg_values() { return arg_values_; }
79
0
  std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
80
0
    return arg_convertables_;
81
0
  }
82
0
  unsigned int flags() const { return flags_; }
83
0
  int64_t ts() { return ts_; }
84
0
  int64_t tts() { return tts_; }
85
0
  uint64_t duration() { return duration_; }
86
0
  uint64_t cpu_duration() { return cpu_duration_; }
87
88
 private:
89
  int pid_;
90
  int tid_;
91
  char phase_;
92
  const char* name_;
93
  const char* scope_;
94
  const uint8_t* category_enabled_flag_;
95
  uint64_t id_;
96
  uint64_t bind_id_;
97
  int num_args_ = 0;
98
  const char* arg_names_[kTraceMaxNumArgs];
99
  uint8_t arg_types_[kTraceMaxNumArgs];
100
  ArgValue arg_values_[kTraceMaxNumArgs];
101
  std::unique_ptr<v8::ConvertableToTraceFormat>
102
      arg_convertables_[kTraceMaxNumArgs];
103
  char* parameter_copy_storage_ = nullptr;
104
  unsigned int flags_;
105
  int64_t ts_;
106
  int64_t tts_;
107
  uint64_t duration_;
108
  uint64_t cpu_duration_;
109
110
  // Disallow copy and assign
111
  TraceObject(const TraceObject&) = delete;
112
  void operator=(const TraceObject&) = delete;
113
};
114
115
class V8_PLATFORM_EXPORT TraceWriter {
116
 public:
117
  TraceWriter() = default;
118
  virtual ~TraceWriter() = default;
119
  virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
120
  virtual void Flush() = 0;
121
122
  static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
123
  static TraceWriter* CreateJSONTraceWriter(std::ostream& stream,
124
                                            const std::string& tag);
125
126
  static TraceWriter* CreateSystemInstrumentationTraceWriter();
127
128
 private:
129
  // Disallow copy and assign
130
  TraceWriter(const TraceWriter&) = delete;
131
  void operator=(const TraceWriter&) = delete;
132
};
133
134
class V8_PLATFORM_EXPORT TraceBufferChunk {
135
 public:
136
  explicit TraceBufferChunk(uint32_t seq);
137
138
  void Reset(uint32_t new_seq);
139
0
  bool IsFull() const { return next_free_ == kChunkSize; }
140
  TraceObject* AddTraceEvent(size_t* event_index);
141
0
  TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
142
143
0
  uint32_t seq() const { return seq_; }
144
0
  size_t size() const { return next_free_; }
145
146
  static const size_t kChunkSize = 64;
147
148
 private:
149
  size_t next_free_ = 0;
150
  TraceObject chunk_[kChunkSize];
151
  uint32_t seq_;
152
153
  // Disallow copy and assign
154
  TraceBufferChunk(const TraceBufferChunk&) = delete;
155
  void operator=(const TraceBufferChunk&) = delete;
156
};
157
158
class V8_PLATFORM_EXPORT TraceBuffer {
159
 public:
160
0
  TraceBuffer() = default;
161
0
  virtual ~TraceBuffer() = default;
162
163
  virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
164
  virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
165
  virtual bool Flush() = 0;
166
167
  static const size_t kRingBufferChunks = 1024;
168
169
  static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
170
                                                  TraceWriter* trace_writer);
171
172
 private:
173
  // Disallow copy and assign
174
  TraceBuffer(const TraceBuffer&) = delete;
175
  void operator=(const TraceBuffer&) = delete;
176
};
177
178
// Options determines how the trace buffer stores data.
179
enum TraceRecordMode {
180
  // Record until the trace buffer is full.
181
  RECORD_UNTIL_FULL,
182
183
  // Record until the user ends the trace. The trace buffer is a fixed size
184
  // and we use it as a ring buffer during recording.
185
  RECORD_CONTINUOUSLY,
186
187
  // Record until the trace buffer is full, but with a huge buffer size.
188
  RECORD_AS_MUCH_AS_POSSIBLE,
189
190
  // Echo to console. Events are discarded.
191
  ECHO_TO_CONSOLE,
192
};
193
194
class V8_PLATFORM_EXPORT TraceConfig {
195
 public:
196
  typedef std::vector<std::string> StringList;
197
198
  static TraceConfig* CreateDefaultTraceConfig();
199
200
0
  TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
201
0
  TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
202
0
  const StringList& GetEnabledCategories() const {
203
0
    return included_categories_;
204
0
  }
205
0
  bool IsSystraceEnabled() const { return enable_systrace_; }
206
0
  bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
207
208
0
  void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
209
0
  void EnableSystrace() { enable_systrace_ = true; }
210
0
  void EnableArgumentFilter() { enable_argument_filter_ = true; }
211
212
  void AddIncludedCategory(const char* included_category);
213
214
  bool IsCategoryGroupEnabled(const char* category_group) const;
215
216
 private:
217
  TraceRecordMode record_mode_;
218
  bool enable_systrace_ : 1;
219
  bool enable_argument_filter_ : 1;
220
  StringList included_categories_;
221
222
  // Disallow copy and assign
223
  TraceConfig(const TraceConfig&) = delete;
224
  void operator=(const TraceConfig&) = delete;
225
};
226
227
#if defined(_MSC_VER)
228
#define V8_PLATFORM_NON_EXPORTED_BASE(code) \
229
  __pragma(warning(suppress : 4275)) code
230
#else
231
#define V8_PLATFORM_NON_EXPORTED_BASE(code) code
232
#endif  // defined(_MSC_VER)
233
234
class V8_PLATFORM_EXPORT TracingController
235
    : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
236
 public:
237
  TracingController();
238
  ~TracingController() override;
239
240
#if defined(V8_USE_PERFETTO)
241
  // Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides
242
  // the output stream for the JSON trace data.
243
  void InitializeForPerfetto(std::ostream* output_stream);
244
  // Provide an optional listener for testing that will receive trace events.
245
  // Must be called before StartTracing().
246
  void SetTraceEventListenerForTesting(TraceEventListener* listener);
247
#else   // defined(V8_USE_PERFETTO)
248
  // The pointer returned from GetCategoryGroupEnabled() points to a value with
249
  // zero or more of the following bits. Used in this class only. The
250
  // TRACE_EVENT macros should only use the value as a bool. These values must
251
  // be in sync with macro values in TraceEvent.h in Blink.
252
  enum CategoryGroupEnabledFlags {
253
    // Category group enabled for the recording mode.
254
    ENABLED_FOR_RECORDING = 1 << 0,
255
    // Category group enabled by SetEventCallbackEnabled().
256
    ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
257
    // Category group enabled to export events to ETW.
258
    ENABLED_FOR_ETW_EXPORT = 1 << 3
259
  };
260
261
  // Takes ownership of |trace_buffer|.
262
  void Initialize(TraceBuffer* trace_buffer);
263
264
  // v8::TracingController implementation.
265
  const uint8_t* GetCategoryGroupEnabled(const char* category_group) override;
266
  uint64_t AddTraceEvent(
267
      char phase, const uint8_t* category_enabled_flag, const char* name,
268
      const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
269
      const char** arg_names, const uint8_t* arg_types,
270
      const uint64_t* arg_values,
271
      std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
272
      unsigned int flags) override;
273
  uint64_t AddTraceEventWithTimestamp(
274
      char phase, const uint8_t* category_enabled_flag, const char* name,
275
      const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
276
      const char** arg_names, const uint8_t* arg_types,
277
      const uint64_t* arg_values,
278
      std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
279
      unsigned int flags, int64_t timestamp) override;
280
  void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
281
                                const char* name, uint64_t handle) override;
282
283
  static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
284
285
  void AddTraceStateObserver(
286
      v8::TracingController::TraceStateObserver* observer) override;
287
  void RemoveTraceStateObserver(
288
      v8::TracingController::TraceStateObserver* observer) override;
289
#endif  // !defined(V8_USE_PERFETTO)
290
291
  void StartTracing(TraceConfig* trace_config);
292
  void StopTracing();
293
294
 protected:
295
#if !defined(V8_USE_PERFETTO)
296
  virtual int64_t CurrentTimestampMicroseconds();
297
  virtual int64_t CurrentCpuTimestampMicroseconds();
298
#endif  // !defined(V8_USE_PERFETTO)
299
300
 private:
301
#if !defined(V8_USE_PERFETTO)
302
  void UpdateCategoryGroupEnabledFlag(size_t category_index);
303
  void UpdateCategoryGroupEnabledFlags();
304
#endif  // !defined(V8_USE_PERFETTO)
305
306
  std::unique_ptr<base::Mutex> mutex_;
307
  std::unique_ptr<TraceConfig> trace_config_;
308
  std::atomic_bool recording_{false};
309
310
#if defined(V8_USE_PERFETTO)
311
  std::ostream* output_stream_ = nullptr;
312
  std::unique_ptr<perfetto::trace_processor::TraceProcessorStorage>
313
      trace_processor_;
314
  TraceEventListener* listener_for_testing_ = nullptr;
315
  std::unique_ptr<perfetto::TracingSession> tracing_session_;
316
#else   // !defined(V8_USE_PERFETTO)
317
  std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
318
  std::unique_ptr<TraceBuffer> trace_buffer_;
319
#endif  // !defined(V8_USE_PERFETTO)
320
321
  // Disallow copy and assign
322
  TracingController(const TracingController&) = delete;
323
  void operator=(const TracingController&) = delete;
324
};
325
326
#undef V8_PLATFORM_NON_EXPORTED_BASE
327
328
}  // namespace tracing
329
}  // namespace platform
330
}  // namespace v8
331
332
#endif  // V8_LIBPLATFORM_V8_TRACING_H_