5#ifndef V8_TRACING_TRACE_EVENT_H_
6#define V8_TRACING_TRACE_EVENT_H_
14#if defined(V8_USE_PERFETTO)
15#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
44#if !defined(V8_USE_PERFETTO)
50#define TRACE_STR_COPY(str) v8::internal::tracing::TraceStringWithCopy(str)
54#define TRACE_ID_WITH_SCOPE(scope, id) \
55 v8::internal::tracing::TraceID::WithScope(scope, id)
57#define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
58 TRACE_EVENT_API_LOAD_CATEGORY_GROUP_ENABLED() & \
59 (kEnabledForRecording_CategoryGroupEnabledFlags | \
60 kEnabledForEventCallback_CategoryGroupEnabledFlags)
65#define INTERNAL_TRACE_MEMORY(category, name)
80#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
81 v8::internal::tracing::TraceEventHelper::GetTracingController() \
82 ->GetCategoryGroupEnabled
87#define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED UNIMPLEMENTED()
102#define TRACE_EVENT_API_ADD_TRACE_EVENT v8::internal::tracing::AddTraceEventImpl
118#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP \
119 v8::internal::tracing::AddTraceEventWithTimestampImpl
126#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
127 v8::internal::tracing::TraceEventHelper::GetTracingController() \
128 ->UpdateTraceEventDuration
132#define TRACE_EVENT_API_ATOMIC_WORD v8::base::AtomicWord
133#define TRACE_EVENT_API_ATOMIC_LOAD(var) v8::base::Acquire_Load(&(var))
134#define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
135 v8::base::Release_Store(&(var), (value))
139#define TRACE_EVENT_API_LOAD_CATEGORY_GROUP_ENABLED() \
140 v8::base::Relaxed_Load(reinterpret_cast<const v8::base::Atomic8*>( \
141 INTERNAL_TRACE_EVENT_UID(category_group_enabled)))
148#define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b
149#define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b)
150#define INTERNAL_TRACE_EVENT_UID(name_prefix) \
151 INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
160#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
161 category_group, atomic, category_group_enabled) \
162 category_group_enabled = \
163 reinterpret_cast<const uint8_t*>(TRACE_EVENT_API_ATOMIC_LOAD(atomic)); \
164 if (!category_group_enabled) { \
165 category_group_enabled = \
166 TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
167 TRACE_EVENT_API_ATOMIC_STORE( \
168 atomic, reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
169 category_group_enabled)); \
172#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
173 static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
174 const uint8_t* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
175 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
176 category_group, INTERNAL_TRACE_EVENT_UID(atomic), \
177 INTERNAL_TRACE_EVENT_UID(category_group_enabled));
181#define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
183 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
184 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
185 v8::internal::tracing::AddTraceEvent( \
186 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
187 v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \
188 v8::internal::tracing::kNoId, flags, ##__VA_ARGS__); \
195#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
196 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
197 v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
198 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
199 uint64_t h = v8::internal::tracing::AddTraceEvent( \
200 TRACE_EVENT_PHASE_COMPLETE, \
201 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
202 v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \
203 v8::internal::tracing::kNoId, TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
204 INTERNAL_TRACE_EVENT_UID(tracer) \
205 .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
209#define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \
210 bind_id, flow_flags, ...) \
211 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
212 v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
213 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
214 unsigned int trace_event_flags = flow_flags; \
215 v8::internal::tracing::TraceID trace_event_bind_id(bind_id, \
216 &trace_event_flags); \
217 uint64_t h = v8::internal::tracing::AddTraceEvent( \
218 TRACE_EVENT_PHASE_COMPLETE, \
219 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
220 v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \
221 trace_event_bind_id.raw_id(), trace_event_flags, ##__VA_ARGS__); \
222 INTERNAL_TRACE_EVENT_UID(tracer) \
223 .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
229#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \
232 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
233 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
234 unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
235 v8::internal::tracing::TraceID trace_event_trace_id(id, \
236 &trace_event_flags); \
237 v8::internal::tracing::AddTraceEvent( \
238 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
239 trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
240 v8::internal::tracing::kNoId, trace_event_flags, ##__VA_ARGS__); \
245#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
246 timestamp, flags, ...) \
248 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
249 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
250 v8::internal::tracing::AddTraceEventWithTimestamp( \
251 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
252 v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \
253 v8::internal::tracing::kNoId, flags, timestamp, ##__VA_ARGS__); \
258#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP( \
259 phase, category_group, name, id, timestamp, flags, ...) \
261 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
262 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
263 unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
264 v8::internal::tracing::TraceID trace_event_trace_id(id, \
265 &trace_event_flags); \
266 v8::internal::tracing::AddTraceEventWithTimestamp( \
267 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
268 trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
269 v8::internal::tracing::kNoId, trace_event_flags, timestamp, \
277#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
278 phase, category_group, name, id, thread_id, timestamp, flags, ...) \
279 INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP( \
280 phase, category_group, name, id, timestamp, flags, ##__VA_ARGS__)
282#define TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name) \
283 INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name)
285#ifdef V8_RUNTIME_CALL_STATS
286#define INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name) \
287 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
288 v8::internal::tracing::CallStatsScopedTracer INTERNAL_TRACE_EVENT_UID( \
290 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
291 INTERNAL_TRACE_EVENT_UID(tracer) \
292 .Initialize(isolate, INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
296#define INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name)
333 :
raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(
raw_id))) {}
377 operator const char*()
const {
return str_; }
384 char phase,
const uint8_t* category_group_enabled,
const char* name,
385 const char* scope, uint64_t
id, uint64_t bind_id, int32_t num_args,
386 const char** arg_names,
const uint8_t* arg_types,
387 const uint64_t* arg_values,
unsigned int flags) {
388 std::unique_ptr<ConvertableToTraceFormat> arg_convertables[2];
391 static_cast<intptr_t
>(arg_values[0])));
395 static_cast<intptr_t
>(arg_values[1])));
400 return controller->
AddTraceEvent(phase, category_group_enabled, name, scope,
401 id, bind_id, num_args, arg_names, arg_types,
402 arg_values, arg_convertables, flags);
406 char phase,
const uint8_t* category_group_enabled,
const char* name,
407 const char* scope, uint64_t
id, uint64_t bind_id, int32_t num_args,
408 const char** arg_names,
const uint8_t* arg_types,
409 const uint64_t* arg_values,
unsigned int flags, int64_t timestamp) {
410 std::unique_ptr<ConvertableToTraceFormat> arg_convertables[2];
413 static_cast<intptr_t
>(arg_values[0])));
417 static_cast<intptr_t
>(arg_values[1])));
423 phase, category_group_enabled, name, scope,
id, bind_id, num_args,
424 arg_names, arg_types, arg_values, arg_convertables, flags, timestamp);
433 requires(std::is_integral<T>::value || std::is_enum<T>::value)
435 *type = std::is_same<T, bool>::value
439 *value =
static_cast<uint64_t
>(arg);
442#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, value_type_id) \
443 static V8_INLINE void SetTraceValue(actual_type arg, unsigned char* type, \
445 *type = value_type_id; \
447 static_assert(sizeof(arg) <= sizeof(*value)); \
448 memcpy(value, &arg, sizeof(arg)); \
455#undef INTERNAL_DECLARE_SET_TRACE_VALUE
458 unsigned char* type, uint64_t* value) {
460 *value =
static_cast<uint64_t
>(
reinterpret_cast<intptr_t
>(convertable_value));
466 requires std::is_convertible<T*, ConvertableToTraceFormat*>::value
478 const uint8_t* category_group_enabled,
479 const char* name,
const char* scope,
480 uint64_t
id, uint64_t bind_id,
481 unsigned int flags) {
484 nullptr,
nullptr,
nullptr, flags);
487template <
class ARG1_TYPE>
489 char phase,
const uint8_t* category_group_enabled,
const char* name,
490 const char* scope, uint64_t
id, uint64_t bind_id,
unsigned int flags,
491 const char* arg1_name, ARG1_TYPE&& arg1_val) {
492 const int num_args = 1;
495 SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value);
497 phase, category_group_enabled, name, scope,
id, bind_id, num_args,
498 &arg1_name, &arg_type, &arg_value, flags);
501template <
class ARG1_TYPE,
class ARG2_TYPE>
503 char phase,
const uint8_t* category_group_enabled,
const char* name,
504 const char* scope, uint64_t
id, uint64_t bind_id,
unsigned int flags,
505 const char* arg1_name, ARG1_TYPE&& arg1_val,
const char* arg2_name,
506 ARG2_TYPE&& arg2_val) {
507 const int num_args = 2;
508 const char* arg_names[2] = {arg1_name, arg2_name};
509 unsigned char arg_types[2];
510 uint64_t arg_values[2];
511 SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0],
513 SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1],
516 phase, category_group_enabled, name, scope,
id, bind_id, num_args,
517 arg_names, arg_types, arg_values, flags);
521 char phase,
const uint8_t* category_group_enabled,
const char* name,
522 const char* scope, uint64_t
id, uint64_t bind_id,
unsigned int flags,
525 phase, category_group_enabled, name, scope,
id, bind_id,
kZeroNumArgs,
526 nullptr,
nullptr,
nullptr, flags, timestamp);
529template <
class ARG1_TYPE>
531 char phase,
const uint8_t* category_group_enabled,
const char* name,
532 const char* scope, uint64_t
id, uint64_t bind_id,
unsigned int flags,
533 int64_t timestamp,
const char* arg1_name, ARG1_TYPE&& arg1_val) {
534 const int num_args = 1;
537 SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value);
539 phase, category_group_enabled, name, scope,
id, bind_id, num_args,
540 &arg1_name, &arg_type, &arg_value, flags, timestamp);
543template <
class ARG1_TYPE,
class ARG2_TYPE>
545 char phase,
const uint8_t* category_group_enabled,
const char* name,
546 const char* scope, uint64_t
id, uint64_t bind_id,
unsigned int flags,
547 int64_t timestamp,
const char* arg1_name, ARG1_TYPE&& arg1_val,
548 const char* arg2_name, ARG2_TYPE&& arg2_val) {
549 const int num_args = 2;
550 const char* arg_names[2] = {arg1_name, arg2_name};
551 unsigned char arg_types[2];
552 uint64_t arg_values[2];
553 SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0],
555 SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1],
558 phase, category_group_enabled, name, scope,
id, bind_id, num_args,
559 arg_names, arg_types, arg_values, flags, timestamp);
576 void Initialize(
const uint8_t* category_group_enabled,
const char* name,
577 uint64_t event_handle) {
599#ifdef V8_RUNTIME_CALL_STATS
601class CallStatsScopedTracer {
603 CallStatsScopedTracer() : p_data_(
nullptr) {}
604 ~CallStatsScopedTracer() {
611 const uint8_t* category_group_enabled,
const char* name);
614 void AddEndTraceEvent();
616 const uint8_t* category_group_enabled;
620 bool has_parent_scope_;
632#ifdef V8_RUNTIME_CALL_STATS
634#define TRACE_EVENT_CALL_STATS_SCOPED(isolate, category, name) \
635 struct PERFETTO_UID(ScopedEvent) { \
636 struct ScopedStats { \
637 ScopedStats(v8::internal::Isolate* isolate_arg, int) { \
638 TRACE_EVENT_BEGIN(category, name, [&](perfetto::EventContext) { \
639 isolate_ = isolate_arg; \
640 internal::RuntimeCallStats* table = \
641 isolate_->counters()->runtime_call_stats(); \
642 has_parent_scope_ = table->InUse(); \
643 if (!has_parent_scope_) table->Reset(); \
647 TRACE_EVENT_END(category, [&](perfetto::EventContext ctx) { \
648 if (!has_parent_scope_ && isolate_) { \
650 auto value = v8::tracing::TracedValue::Create(); \
651 isolate_->counters()->runtime_call_stats()->Dump(value.get()); \
652 auto annotation = ctx.event()->add_debug_annotations(); \
653 annotation->set_name("runtime-call-stats"); \
654 value->Add(annotation); \
658 v8::internal::Isolate* isolate_ = nullptr; \
659 bool has_parent_scope_ = false; \
661 } PERFETTO_UID(scoped_event) { \
665#define TRACE_EVENT_CALL_STATS_SCOPED(isolate, category, name)
uint8_t data_[MAX_STACK_LENGTH]
virtual uint64_t AddTraceEventWithTimestamp(char phase, const uint8_t *category_enabled_flag, const char *name, const char *scope, uint64_t id, uint64_t bind_id, int32_t num_args, const char **arg_names, const uint8_t *arg_types, const uint64_t *arg_values, std::unique_ptr< ConvertableToTraceFormat > *arg_convertables, unsigned int flags, int64_t timestamp)
virtual uint64_t AddTraceEvent(char phase, const uint8_t *category_enabled_flag, const char *name, const char *scope, uint64_t id, uint64_t bind_id, int32_t num_args, const char **arg_names, const uint8_t *arg_types, const uint64_t *arg_values, std::unique_ptr< ConvertableToTraceFormat > *arg_convertables, unsigned int flags)
void Initialize(const uint8_t *category_group_enabled, const char *name, uint64_t event_handle)
static V8_EXPORT_PRIVATE v8::TracingController * GetTracingController()
WithScope(const char *scope, uint64_t raw_id)
const char * scope() const
TraceID(int raw_id, unsigned int *flags)
TraceID(int64_t raw_id, unsigned int *flags)
TraceID(unsigned int raw_id, unsigned int *flags)
TraceID(signed char raw_id, unsigned int *flags)
TraceID(const void *raw_id, unsigned int *flags)
const char * scope() const
TraceID(unsigned char raw_id, unsigned int *flags)
TraceID(uint64_t raw_id, unsigned int *flags)
TraceID(WithScope scoped_id, unsigned int *flags)
TraceID(uint16_t raw_id, unsigned int *flags)
TraceID(int16_t raw_id, unsigned int *flags)
TraceStringWithCopy(const char *str)
Atomic8 Relaxed_Load(volatile const Atomic8 *ptr)
static V8_INLINE uint64_t AddTraceEventImpl(char phase, const uint8_t *category_group_enabled, const char *name, const char *scope, uint64_t id, uint64_t bind_id, int32_t num_args, const char **arg_names, const uint8_t *arg_types, const uint64_t *arg_values, unsigned int flags)
static V8_INLINE uint64_t AddTraceEvent(char phase, const uint8_t *category_group_enabled, const char *name, const char *scope, uint64_t id, uint64_t bind_id, unsigned int flags)
const decltype(nullptr) kGlobalScope
static V8_INLINE void SetTraceValue(T arg, unsigned char *type, uint64_t *value)
static V8_INLINE uint64_t AddTraceEventWithTimestamp(char phase, const uint8_t *category_group_enabled, const char *name, const char *scope, uint64_t id, uint64_t bind_id, unsigned int flags, int64_t timestamp)
static V8_INLINE uint64_t AddTraceEventWithTimestampImpl(char phase, const uint8_t *category_group_enabled, const char *name, const char *scope, uint64_t id, uint64_t bind_id, int32_t num_args, const char **arg_names, const uint8_t *arg_types, const uint64_t *arg_values, unsigned int flags, int64_t timestamp)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
#define DCHECK_LE(v1, v2)
#define V8_EXPORT_PRIVATE
const uint8_t * category_group_enabled
#define TRACE_VALUE_TYPE_STRING
#define TRACE_VALUE_TYPE_BOOL
#define TRACE_VALUE_TYPE_POINTER
#define TRACE_VALUE_TYPE_COPY_STRING
#define TRACE_VALUE_TYPE_INT
#define TRACE_VALUE_TYPE_UINT
#define TRACE_VALUE_TYPE_DOUBLE
#define TRACE_VALUE_TYPE_CONVERTABLE
#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION
#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP
CategoryGroupEnabledFlags
@ kEnabledForEventCallback_CategoryGroupEnabledFlags
@ kEnabledForRecording_CategoryGroupEnabledFlags
@ kEnabledForETWExport_CategoryGroupEnabledFlags
#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, value_type_id)
#define TRACE_EVENT_API_ADD_TRACE_EVENT
#define V8_UNLIKELY(condition)