Node.js  v8.x
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
trace_event.h
Go to the documentation of this file.
1 // Copyright 2015 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 SRC_TRACING_TRACE_EVENT_H_
6 #define SRC_TRACING_TRACE_EVENT_H_
7 
8 #include <stddef.h>
9 
10 #include "node_platform.h"
11 #include "v8-platform.h"
12 #include "trace_event_common.h"
13 
14 // This header file defines implementation details of how the trace macros in
15 // trace_event_common.h collect and store trace events. Anything not
16 // implementation-specific should go in trace_macros_common.h instead of here.
17 
18 
19 // The pointer returned from GetCategoryGroupEnabled() points to a
20 // value with zero or more of the following bits. Used in this class only.
21 // The TRACE_EVENT macros should only use the value as a bool.
22 // These values must be in sync with macro values in trace_log.h in
23 // chromium.
25  // Category group enabled for the recording mode.
27  // Category group enabled by SetEventCallbackEnabled().
29  // Category group enabled to export events to ETW.
31 };
32 
33 // By default, const char* asrgument values are assumed to have long-lived scope
34 // and will not be copied. Use this macro to force a const char* to be copied.
35 #define TRACE_STR_COPY(str) node::tracing::TraceStringWithCopy(str)
36 
37 // By default, uint64 ID argument values are not mangled with the Process ID in
38 // TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
39 #define TRACE_ID_MANGLE(id) node::tracing::TraceID::ForceMangle(id)
40 
41 // By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
42 // macros. Use this macro to prevent Process ID mangling.
43 #define TRACE_ID_DONT_MANGLE(id) node::tracing::TraceID::DontMangle(id)
44 
45 // By default, trace IDs are eventually converted to a single 64-bit number. Use
46 // this macro to add a scope string.
47 #define TRACE_ID_WITH_SCOPE(scope, id) \
48  trace_event_internal::TraceID::WithScope(scope, id)
49 
50 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
51  *INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \
52  (kEnabledForRecording_CategoryGroupEnabledFlags | \
53  kEnabledForEventCallback_CategoryGroupEnabledFlags)
54 
55 // The following macro has no implementation, but it needs to exist since
56 // it gets called from scoped trace events. It cannot call UNIMPLEMENTED()
57 // since an empty implementation is a valid one.
58 #define INTERNAL_TRACE_MEMORY(category, name)
59 
61 // Implementation specific tracing API definitions.
62 
63 // Get a pointer to the enabled state of the given trace category. Only
64 // long-lived literal strings should be given as the category group. The
65 // returned pointer can be held permanently in a local static for example. If
66 // the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
67 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
68 // between the load of the tracing state and the call to
69 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
70 // for best performance when tracing is disabled.
71 // const uint8_t*
72 // TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
73 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
74  node::tracing::TraceEventHelper::GetTracingController() \
75  ->GetCategoryGroupEnabled
76 
77 // Get the number of times traces have been recorded. This is used to implement
78 // the TRACE_EVENT_IS_NEW_TRACE facility.
79 // unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED()
80 #define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED UNIMPLEMENTED()
81 
82 // Add a trace event to the platform tracing system.
83 // uint64_t TRACE_EVENT_API_ADD_TRACE_EVENT(
84 // char phase,
85 // const uint8_t* category_group_enabled,
86 // const char* name,
87 // const char* scope,
88 // uint64_t id,
89 // uint64_t bind_id,
90 // int num_args,
91 // const char** arg_names,
92 // const uint8_t* arg_types,
93 // const uint64_t* arg_values,
94 // unsigned int flags)
95 #define TRACE_EVENT_API_ADD_TRACE_EVENT node::tracing::AddTraceEventImpl
96 
97 // Set the duration field of a COMPLETE trace event.
98 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
99 // const uint8_t* category_group_enabled,
100 // const char* name,
101 // uint64_t id)
102 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
103  node::tracing::TraceEventHelper::GetTracingController() \
104  ->UpdateTraceEventDuration
105 
106 // Defines atomic operations used internally by the tracing system.
107 #define TRACE_EVENT_API_ATOMIC_WORD intptr_t
108 #define TRACE_EVENT_API_ATOMIC_LOAD(var) (var)
109 #define TRACE_EVENT_API_ATOMIC_STORE(var, value) (var) = (value)
110 
112 
113 // Implementation detail: trace event macros create temporary variables
114 // to keep instrumentation overhead low. These macros give each temporary
115 // variable a unique name based on the line number to prevent name collisions.
116 #define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b
117 #define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b)
118 #define INTERNAL_TRACE_EVENT_UID(name_prefix) \
119  INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
120 
121 // Implementation detail: internal macro to create static category.
122 // No barriers are needed, because this code is designed to operate safely
123 // even when the unsigned char* points to garbage data (which may be the case
124 // on processors without cache coherency).
125 // TODO(fmeawad): This implementation contradicts that we can have a different
126 // configuration for each isolate,
127 // https://code.google.com/p/v8/issues/detail?id=4563
128 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
129  category_group, atomic, category_group_enabled) \
130  category_group_enabled = \
131  reinterpret_cast<const uint8_t*>(TRACE_EVENT_API_ATOMIC_LOAD(atomic)); \
132  if (!category_group_enabled) { \
133  category_group_enabled = \
134  TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
135  TRACE_EVENT_API_ATOMIC_STORE( \
136  atomic, reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
137  category_group_enabled)); \
138  }
139 
140 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
141  static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
142  const uint8_t* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
143  INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
144  category_group, INTERNAL_TRACE_EVENT_UID(atomic), \
145  INTERNAL_TRACE_EVENT_UID(category_group_enabled));
146 
147 // Implementation detail: internal macro to create static category and add
148 // event if the category is enabled.
149 #define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
150  do { \
151  INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
152  if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
153  node::tracing::AddTraceEvent( \
154  phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
155  node::tracing::kGlobalScope, node::tracing::kNoId, \
156  node::tracing::kNoId, flags, ##__VA_ARGS__); \
157  } \
158  } while (0)
159 
160 // Implementation detail: internal macro to create static category and add begin
161 // event if the category is enabled. Also adds the end event when the scope
162 // ends.
163 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
164  INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
165  node::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
166  if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
167  uint64_t h = node::tracing::AddTraceEvent( \
168  TRACE_EVENT_PHASE_COMPLETE, \
169  INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
170  node::tracing::kGlobalScope, node::tracing::kNoId, \
171  node::tracing::kNoId, TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
172  INTERNAL_TRACE_EVENT_UID(tracer) \
173  .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
174  h); \
175  }
176 
177 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \
178  bind_id, flow_flags, ...) \
179  INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
180  node::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
181  if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
182  unsigned int trace_event_flags = flow_flags; \
183  node::tracing::TraceID trace_event_bind_id(bind_id, \
184  &trace_event_flags); \
185  uint64_t h = node::tracing::AddTraceEvent( \
186  TRACE_EVENT_PHASE_COMPLETE, \
187  INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
188  node::tracing::kGlobalScope, node::tracing::kNoId, \
189  trace_event_bind_id.raw_id(), trace_event_flags, ##__VA_ARGS__); \
190  INTERNAL_TRACE_EVENT_UID(tracer) \
191  .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
192  h); \
193  }
194 
195 // Implementation detail: internal macro to create static category and add
196 // event if the category is enabled.
197 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \
198  flags, ...) \
199  do { \
200  INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
201  if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
202  unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
203  node::tracing::TraceID trace_event_trace_id(id, \
204  &trace_event_flags); \
205  node::tracing::AddTraceEvent( \
206  phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
207  trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
208  node::tracing::kNoId, trace_event_flags, ##__VA_ARGS__); \
209  } \
210  } while (0)
211 
212 // Adds a trace event with a given timestamp. Not Implemented.
213 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
214  timestamp, flags, ...) \
215  UNIMPLEMENTED()
216 
217 // Adds a trace event with a given id and timestamp. Not Implemented.
218 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP( \
219  phase, category_group, name, id, timestamp, flags, ...) \
220  UNIMPLEMENTED()
221 
222 // Adds a trace event with a given id, thread_id, and timestamp. Not
223 // Implemented.
224 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
225  phase, category_group, name, id, thread_id, timestamp, flags, ...) \
226  UNIMPLEMENTED()
227 
228 // Enter and leave a context based on the current scope.
229 #define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \
230  struct INTERNAL_TRACE_EVENT_UID(ScopedContext) { \
231  public: \
232  INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) { \
233  TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_); \
234  } \
235  ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() { \
236  TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_); \
237  } \
238  \
239  private: \
240  /* Local class friendly DISALLOW_COPY_AND_ASSIGN */ \
241  INTERNAL_TRACE_EVENT_UID(ScopedContext) \
242  (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {} \
243  void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {} \
244  uint64_t cid_; \
245  }; \
246  INTERNAL_TRACE_EVENT_UID(ScopedContext) \
247  INTERNAL_TRACE_EVENT_UID(scoped_context)(context);
248 
249 namespace node {
250 namespace tracing {
251 
252 // Specify these values when the corresponding argument of AddTraceEvent is not
253 // used.
254 const int kZeroNumArgs = 0;
255 const decltype(nullptr) kGlobalScope = nullptr;
256 const uint64_t kNoId = 0;
257 
258 extern intptr_t kRuntimeCallStatsTracingEnabled;
259 
261  public:
262  static v8::TracingController* GetTracingController();
263  static void SetTracingController(v8::TracingController* controller);
264 };
265 
266 // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
267 // are by default mangled with the Process ID so that they are unlikely to
268 // collide when the same pointer is used on different processes.
269 class TraceID {
270  public:
271  class WithScope {
272  public:
273  WithScope(const char* scope, uint64_t raw_id)
274  : scope_(scope), raw_id_(raw_id) {}
275  uint64_t raw_id() const { return raw_id_; }
276  const char* scope() const { return scope_; }
277 
278  private:
279  const char* scope_ = nullptr;
280  uint64_t raw_id_;
281  };
282 
283  class DontMangle {
284  public:
285  explicit DontMangle(const void* raw_id)
286  : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
287  explicit DontMangle(uint64_t raw_id) : raw_id_(raw_id) {}
288  explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {}
289  explicit DontMangle(uint16_t raw_id) : raw_id_(raw_id) {}
290  explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {}
291  explicit DontMangle(int64_t raw_id)
292  : raw_id_(static_cast<uint64_t>(raw_id)) {}
293  explicit DontMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
294  explicit DontMangle(int16_t raw_id)
295  : raw_id_(static_cast<uint64_t>(raw_id)) {}
296  explicit DontMangle(signed char raw_id)
297  : raw_id_(static_cast<uint64_t>(raw_id)) {}
298  explicit DontMangle(WithScope scoped_id)
299  : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
300  const char* scope() const { return scope_; }
301  uint64_t raw_id() const { return raw_id_; }
302 
303  private:
304  const char* scope_ = nullptr;
305  uint64_t raw_id_;
306  };
307 
308  class ForceMangle {
309  public:
310  explicit ForceMangle(uint64_t raw_id) : raw_id_(raw_id) {}
311  explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {}
312  explicit ForceMangle(uint16_t raw_id) : raw_id_(raw_id) {}
313  explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {}
314  explicit ForceMangle(int64_t raw_id)
315  : raw_id_(static_cast<uint64_t>(raw_id)) {}
316  explicit ForceMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
317  explicit ForceMangle(int16_t raw_id)
318  : raw_id_(static_cast<uint64_t>(raw_id)) {}
319  explicit ForceMangle(signed char raw_id)
320  : raw_id_(static_cast<uint64_t>(raw_id)) {}
321  uint64_t raw_id() const { return raw_id_; }
322 
323  private:
324  uint64_t raw_id_;
325  };
326 
327  TraceID(const void* raw_id, unsigned int* flags)
328  : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
329  *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
330  }
331  TraceID(ForceMangle raw_id, unsigned int* flags) : raw_id_(raw_id.raw_id()) {
332  *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
333  }
334  TraceID(DontMangle maybe_scoped_id, unsigned int* flags)
335  : scope_(maybe_scoped_id.scope()), raw_id_(maybe_scoped_id.raw_id()) {}
336  TraceID(uint64_t raw_id, unsigned int* flags) : raw_id_(raw_id) {
337  (void)flags;
338  }
339  TraceID(unsigned int raw_id, unsigned int* flags) : raw_id_(raw_id) {
340  (void)flags;
341  }
342  TraceID(uint16_t raw_id, unsigned int* flags) : raw_id_(raw_id) {
343  (void)flags;
344  }
345  TraceID(unsigned char raw_id, unsigned int* flags) : raw_id_(raw_id) {
346  (void)flags;
347  }
348  TraceID(int64_t raw_id, unsigned int* flags)
349  : raw_id_(static_cast<uint64_t>(raw_id)) {
350  (void)flags;
351  }
352  TraceID(int raw_id, unsigned int* flags)
353  : raw_id_(static_cast<uint64_t>(raw_id)) {
354  (void)flags;
355  }
356  TraceID(int16_t raw_id, unsigned int* flags)
357  : raw_id_(static_cast<uint64_t>(raw_id)) {
358  (void)flags;
359  }
360  TraceID(signed char raw_id, unsigned int* flags)
361  : raw_id_(static_cast<uint64_t>(raw_id)) {
362  (void)flags;
363  }
364  TraceID(WithScope scoped_id, unsigned int* flags)
365  : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
366 
367  uint64_t raw_id() const { return raw_id_; }
368  const char* scope() const { return scope_; }
369 
370  private:
371  const char* scope_ = nullptr;
372  uint64_t raw_id_;
373 };
374 
375 // Simple union to store various types as uint64_t.
377  bool as_bool;
378  uint64_t as_uint;
379  int64_t as_int;
380  double as_double;
381  const void* as_pointer;
382  const char* as_string;
383 };
384 
385 // Simple container for const char* that should be copied instead of retained.
387  public:
388  explicit TraceStringWithCopy(const char* str) : str_(str) {}
389  operator const char*() const { return str_; }
390 
391  private:
392  const char* str_;
393 };
394 
395 static inline uint64_t AddTraceEventImpl(
396  char phase, const uint8_t* category_group_enabled, const char* name,
397  const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
398  const char** arg_names, const uint8_t* arg_types,
399  const uint64_t* arg_values, unsigned int flags) {
400  std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertibles[2];
401  if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
402  arg_convertibles[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
403  static_cast<intptr_t>(arg_values[0])));
404  }
405  if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) {
406  arg_convertibles[1].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>(
407  static_cast<intptr_t>(arg_values[1])));
408  }
409  // DCHECK(num_args <= 2);
410  v8::TracingController* controller =
412  return controller->AddTraceEvent(phase, category_group_enabled, name, scope, id,
413  bind_id, num_args, arg_names, arg_types,
414  arg_values, arg_convertibles, flags);
415 }
416 
417 // Define SetTraceValue for each allowed type. It stores the type and
418 // value in the return arguments. This allows this API to avoid declaring any
419 // structures so that it is portable to third_party libraries.
420 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member, \
421  value_type_id) \
422  static inline void SetTraceValue(actual_type arg, unsigned char* type, \
423  uint64_t* value) { \
424  TraceValueUnion type_value; \
425  type_value.union_member = arg; \
426  *type = value_type_id; \
427  *value = type_value.as_uint; \
428  }
429 // Simpler form for int types that can be safely casted.
430 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id) \
431  static inline void SetTraceValue(actual_type arg, unsigned char* type, \
432  uint64_t* value) { \
433  *type = value_type_id; \
434  *value = static_cast<uint64_t>(arg); \
435  }
436 
447 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
453 
454 #undef INTERNAL_DECLARE_SET_TRACE_VALUE
455 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
456 
457 static inline void SetTraceValue(v8::ConvertableToTraceFormat* convertable_value,
458  unsigned char* type, uint64_t* value) {
460  *value = static_cast<uint64_t>(reinterpret_cast<intptr_t>(convertable_value));
461 }
462 
463 template <typename T>
464 static inline typename std::enable_if<
465  std::is_convertible<T*, v8::ConvertableToTraceFormat*>::value>::type
466 SetTraceValue(std::unique_ptr<T> ptr, unsigned char* type, uint64_t* value) {
467  SetTraceValue(ptr.release(), type, value);
468 }
469 
470 // These AddTraceEvent template
471 // function is defined here instead of in the macro, because the arg_values
472 // could be temporary objects, such as std::string. In order to store
473 // pointers to the internal c_str and pass through to the tracing API,
474 // the arg_values must live throughout these procedures.
475 
476 static inline uint64_t AddTraceEvent(char phase,
477  const uint8_t* category_group_enabled,
478  const char* name, const char* scope,
479  uint64_t id, uint64_t bind_id,
480  unsigned int flags) {
481  return TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name,
482  scope, id, bind_id, kZeroNumArgs,
483  nullptr, nullptr, nullptr, flags);
484 }
485 
486 template <class ARG1_TYPE>
487 static inline uint64_t AddTraceEvent(
488  char phase, const uint8_t* category_group_enabled, const char* name,
489  const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
490  const char* arg1_name, ARG1_TYPE&& arg1_val) {
491  const int num_args = 1;
492  uint8_t arg_type;
493  uint64_t arg_value;
494  SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value);
496  phase, category_group_enabled, name, scope, id, bind_id, num_args,
497  &arg1_name, &arg_type, &arg_value, flags);
498 }
499 
500 template <class ARG1_TYPE, class ARG2_TYPE>
501 static inline uint64_t AddTraceEvent(
502  char phase, const uint8_t* category_group_enabled, const char* name,
503  const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
504  const char* arg1_name, ARG1_TYPE&& arg1_val, const char* arg2_name,
505  ARG2_TYPE&& arg2_val) {
506  const int num_args = 2;
507  const char* arg_names[2] = {arg1_name, arg2_name};
508  unsigned char arg_types[2];
509  uint64_t arg_values[2];
510  SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0],
511  &arg_values[0]);
512  SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1],
513  &arg_values[1]);
515  phase, category_group_enabled, name, scope, id, bind_id, num_args,
516  arg_names, arg_types, arg_values, flags);
517 }
518 
519 // Used by TRACE_EVENTx macros. Do not use directly.
521  public:
522  // Note: members of data_ intentionally left uninitialized. See Initialize.
523  ScopedTracer() : p_data_(NULL) {}
524 
526  if (p_data_ && *data_.category_group_enabled)
528  data_.category_group_enabled, data_.name, data_.event_handle);
529  }
530 
531  void Initialize(const uint8_t* category_group_enabled, const char* name,
532  uint64_t event_handle) {
533  data_.category_group_enabled = category_group_enabled;
534  data_.name = name;
535  data_.event_handle = event_handle;
536  p_data_ = &data_;
537  }
538 
539  private:
540  // This Data struct workaround is to avoid initializing all the members
541  // in Data during construction of this object, since this object is always
542  // constructed, even when tracing is disabled. If the members of Data were
543  // members of this class instead, compiler warnings occur about potential
544  // uninitialized accesses.
545  struct Data {
546  const uint8_t* category_group_enabled;
547  const char* name;
548  uint64_t event_handle;
549  };
550  Data* p_data_;
551  Data data_;
552 };
553 
554 } // namespace tracing
555 } // namespace node
556 
557 #endif // SRC_TRACING_TRACE_EVENT_H_
TraceStringWithCopy(const char *str)
Definition: trace_event.h:388
intptr_t kRuntimeCallStatsTracingEnabled
#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id)
Definition: trace_event.h:430
#define TRACE_VALUE_TYPE_POINTER
DontMangle(signed char raw_id)
Definition: trace_event.h:296
DontMangle(unsigned char raw_id)
Definition: trace_event.h:290
CategoryGroupEnabledFlags
Definition: trace_event.h:24
const char * scope() const
Definition: trace_event.h:276
TraceID(int raw_id, unsigned int *flags)
Definition: trace_event.h:352
TraceID(uint64_t raw_id, unsigned int *flags)
Definition: trace_event.h:336
TraceID(int64_t raw_id, unsigned int *flags)
Definition: trace_event.h:348
#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION
Definition: trace_event.h:102
#define TRACE_VALUE_TYPE_CONVERTABLE
DontMangle(const void *raw_id)
Definition: trace_event.h:285
const uint64_t kNoId
Definition: trace_event.h:256
TraceID(ForceMangle raw_id, unsigned int *flags)
Definition: trace_event.h:331
TraceID(int16_t raw_id, unsigned int *flags)
Definition: trace_event.h:356
const char * str_
INTERNAL_DECLARE_SET_TRACE_VALUE(const void *, as_pointer, TRACE_VALUE_TYPE_POINTER) INTERNAL_DECLARE_SET_TRACE_VALUE(const char *
DontMangle(unsigned int raw_id)
Definition: trace_event.h:288
TraceID(DontMangle maybe_scoped_id, unsigned int *flags)
Definition: trace_event.h:334
TraceID(uint16_t raw_id, unsigned int *flags)
Definition: trace_event.h:342
ForceMangle(unsigned int raw_id)
Definition: trace_event.h:311
char * Data(Local< Value > val)
Definition: node_buffer.cc:211
#define TRACE_VALUE_TYPE_STRING
TraceID(unsigned int raw_id, unsigned int *flags)
Definition: trace_event.h:339
ForceMangle(unsigned char raw_id)
Definition: trace_event.h:313
#define TRACE_EVENT_API_ADD_TRACE_EVENT
Definition: trace_event.h:95
#define TRACE_VALUE_TYPE_DOUBLE
#define TRACE_VALUE_TYPE_BOOL
void Initialize(const uint8_t *category_group_enabled, const char *name, uint64_t event_handle)
Definition: trace_event.h:531
#define TRACE_VALUE_TYPE_COPY_STRING
#define TRACE_EVENT_FLAG_MANGLE_ID
TraceID(WithScope scoped_id, unsigned int *flags)
Definition: trace_event.h:364
const char * scope() const
Definition: trace_event.h:368
TraceID(const void *raw_id, unsigned int *flags)
Definition: trace_event.h:327
const int kZeroNumArgs
Definition: trace_event.h:254
DontMangle(WithScope scoped_id)
Definition: trace_event.h:298
WithScope(const char *scope, uint64_t raw_id)
Definition: trace_event.h:273
TraceID(unsigned char raw_id, unsigned int *flags)
Definition: trace_event.h:345
#define TRACE_VALUE_TYPE_INT
#define TRACE_VALUE_TYPE_UINT
static v8::TracingController * GetTracingController()
Definition: trace_event.cc:12
TraceID(signed char raw_id, unsigned int *flags)
Definition: trace_event.h:360
uint64_t raw_id() const
Definition: trace_event.h:367
decltype(nullptr) const kGlobalScope
Definition: trace_event.h:255