LCOV - code coverage report
Current view: top level - src/tracing - trace-event.h (source / functions) Hit Total Coverage
Test: app.info Lines: 47 51 92.2 %
Date: 2019-04-17 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.10