v8  7.9.317 (node 13.2.0)
V8 is Google's open source JavaScript engine
v8-tracing.h
Go to the documentation of this file.
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 <fstream>
10 #include <memory>
11 #include <unordered_set>
12 #include <vector>
13 
14 #include "libplatform/libplatform-export.h"
15 #include "v8-platform.h" // NOLINT(build/include)
16 
17 namespace perfetto {
18 class TracingSession;
19 }
20 
21 namespace v8 {
22 
23 namespace base {
24 class Mutex;
25 } // namespace base
26 
27 namespace platform {
28 namespace tracing {
29 
30 class TraceEventListener;
31 class JSONTraceEventListener;
32 
33 const int kTraceMaxNumArgs = 2;
34 
36  public:
37  union ArgValue {
38  bool as_bool;
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  TraceObject() = default;
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);
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  int pid() const { return pid_; }
66  int tid() const { return tid_; }
67  char phase() const { return phase_; }
68  const uint8_t* category_enabled_flag() const {
69  return category_enabled_flag_;
70  }
71  const char* name() const { return name_; }
72  const char* scope() const { return scope_; }
73  uint64_t id() const { return id_; }
74  uint64_t bind_id() const { return bind_id_; }
75  int num_args() const { return num_args_; }
76  const char** arg_names() { return arg_names_; }
77  uint8_t* arg_types() { return arg_types_; }
78  ArgValue* arg_values() { return arg_values_; }
80  return arg_convertables_;
81  }
82  unsigned int flags() const { return flags_; }
83  int64_t ts() { return ts_; }
84  int64_t tts() { return tts_; }
85  uint64_t duration() { return duration_; }
86  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 
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  private:
127  // Disallow copy and assign
128  TraceWriter(const TraceWriter&) = delete;
129  void operator=(const TraceWriter&) = delete;
130 };
131 
133  public:
134  explicit TraceBufferChunk(uint32_t seq);
135 
136  void Reset(uint32_t new_seq);
137  bool IsFull() const { return next_free_ == kChunkSize; }
138  TraceObject* AddTraceEvent(size_t* event_index);
139  TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
140 
141  uint32_t seq() const { return seq_; }
142  size_t size() const { return next_free_; }
143 
144  static const size_t kChunkSize = 64;
145 
146  private:
147  size_t next_free_ = 0;
148  TraceObject chunk_[kChunkSize];
149  uint32_t seq_;
150 
151  // Disallow copy and assign
152  TraceBufferChunk(const TraceBufferChunk&) = delete;
153  void operator=(const TraceBufferChunk&) = delete;
154 };
155 
157  public:
158  TraceBuffer() = default;
159  virtual ~TraceBuffer() = default;
160 
161  virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
162  virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
163  virtual bool Flush() = 0;
164 
165  static const size_t kRingBufferChunks = 1024;
166 
167  static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
168  TraceWriter* trace_writer);
169 
170  private:
171  // Disallow copy and assign
172  TraceBuffer(const TraceBuffer&) = delete;
173  void operator=(const TraceBuffer&) = delete;
174 };
175 
176 // Options determines how the trace buffer stores data.
178  // Record until the trace buffer is full.
180 
181  // Record until the user ends the trace. The trace buffer is a fixed size
182  // and we use it as a ring buffer during recording.
184 
185  // Record until the trace buffer is full, but with a huge buffer size.
187 
188  // Echo to console. Events are discarded.
190 };
191 
193  public:
194  typedef std::vector<std::string> StringList;
195 
197 
198  TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
199  TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
200  bool IsSystraceEnabled() const { return enable_systrace_; }
201  bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
202 
203  void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
204  void EnableSystrace() { enable_systrace_ = true; }
205  void EnableArgumentFilter() { enable_argument_filter_ = true; }
206 
207  void AddIncludedCategory(const char* included_category);
208 
209  bool IsCategoryGroupEnabled(const char* category_group) const;
210 
211  private:
212  TraceRecordMode record_mode_;
213  bool enable_systrace_ : 1;
214  bool enable_argument_filter_ : 1;
215  StringList included_categories_;
216 
217  // Disallow copy and assign
218  TraceConfig(const TraceConfig&) = delete;
219  void operator=(const TraceConfig&) = delete;
220 };
221 
222 #if defined(_MSC_VER)
223 #define V8_PLATFORM_NON_EXPORTED_BASE(code)
224  __pragma(warning(suppress : 4275)) code
225 #else
226 #define V8_PLATFORM_NON_EXPORTED_BASE(code) code
227 #endif // defined(_MSC_VER)
228 
231  public:
232  // The pointer returned from GetCategoryGroupEnabled() points to a value with
233  // zero or more of the following bits. Used in this class only. The
234  // TRACE_EVENT macros should only use the value as a bool. These values must
235  // be in sync with macro values in TraceEvent.h in Blink.
237  // Category group enabled for the recording mode.
239  // Category group enabled by SetEventCallbackEnabled().
241  // Category group enabled to export events to ETW.
242  ENABLED_FOR_ETW_EXPORT = 1 << 3
243  };
244 
246  ~TracingController() override;
247 
248  // Takes ownership of |trace_buffer|.
249  void Initialize(TraceBuffer* trace_buffer);
250 #ifdef V8_USE_PERFETTO
251  // Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides
252  // the output stream for the JSON trace data.
254  // Provide an optional listener for testing that will receive trace events.
255  // Must be called before StartTracing().
257 #endif
258 
259  // v8::TracingController implementation.
260  const uint8_t* GetCategoryGroupEnabled(const char* category_group) override;
261  uint64_t AddTraceEvent(
262  char phase, const uint8_t* category_enabled_flag, const char* name,
263  const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
264  const char** arg_names, const uint8_t* arg_types,
265  const uint64_t* arg_values,
266  std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
267  unsigned int flags) override;
269  char phase, const uint8_t* category_enabled_flag, const char* name,
270  const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
271  const char** arg_names, const uint8_t* arg_types,
272  const uint64_t* arg_values,
273  std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
274  unsigned int flags, int64_t timestamp) override;
275  void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
276  const char* name, uint64_t handle) override;
278  v8::TracingController::TraceStateObserver* observer) override;
280  v8::TracingController::TraceStateObserver* observer) override;
281 
282  void StartTracing(TraceConfig* trace_config);
283  void StopTracing();
284 
285  static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
286 
287  protected:
288  virtual int64_t CurrentTimestampMicroseconds();
290 
291  private:
292  void UpdateCategoryGroupEnabledFlag(size_t category_index);
293  void UpdateCategoryGroupEnabledFlags();
294 
295  std::unique_ptr<TraceBuffer> trace_buffer_;
296  std::unique_ptr<TraceConfig> trace_config_;
297  std::unique_ptr<base::Mutex> mutex_;
298  std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
299  std::atomic_bool recording_{false};
300 #ifdef V8_USE_PERFETTO
301  std::ostream* output_stream_ = nullptr;
305 #endif
306 
307  // Disallow copy and assign
308  TracingController(const TracingController&) = delete;
309  void operator=(const TracingController&) = delete;
310 };
311 
312 #undef V8_PLATFORM_NON_EXPORTED_BASE
313 
314 } // namespace tracing
315 } // namespace platform
316 } // namespace v8
317 
318 #endif // V8_LIBPLATFORM_V8_TRACING_H_