LCOV - code coverage report
Current view: top level - src/tracing - trace-event.h (source / functions) Hit Total Coverage
Test: app.info Lines: 57 62 91.9 %
Date: 2019-02-19 Functions: 4 5 80.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             :   trace_event_internal::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             : // Enter and leave a context based on the current scope.
     274             : #define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \
     275             :   struct INTERNAL_TRACE_EVENT_UID(ScopedContext) {                         \
     276             :    public:                                                                 \
     277             :     INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) {    \
     278             :       TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_);               \
     279             :     }                                                                      \
     280             :     ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() {                           \
     281             :       TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_);               \
     282             :     }                                                                      \
     283             :                                                                            \
     284             :    private:                                                                \
     285             :     /* Local class friendly DISALLOW_COPY_AND_ASSIGN */                    \
     286             :     INTERNAL_TRACE_EVENT_UID(ScopedContext)                                \
     287             :     (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}                    \
     288             :     void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}      \
     289             :     uint64_t cid_;                                                         \
     290             :   };                                                                       \
     291             :   INTERNAL_TRACE_EVENT_UID(ScopedContext)                                  \
     292             :   INTERNAL_TRACE_EVENT_UID(scoped_context)(context);
     293             : 
     294             : #define TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name) \
     295             :   INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name)
     296             : 
     297             : #define INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name)  \
     298             :   INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                      \
     299             :   v8::internal::tracing::CallStatsScopedTracer INTERNAL_TRACE_EVENT_UID(       \
     300             :       tracer);                                                                 \
     301             :   if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {      \
     302             :     INTERNAL_TRACE_EVENT_UID(tracer)                                           \
     303             :         .Initialize(isolate, INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
     304             :                     name);                                                     \
     305             :   }
     306             : 
     307             : namespace v8 {
     308             : namespace internal {
     309             : 
     310             : class Isolate;
     311             : 
     312             : namespace tracing {
     313             : 
     314             : // Specify these values when the corresponding argument of AddTraceEvent is not
     315             : // used.
     316             : const int kZeroNumArgs = 0;
     317             : const decltype(nullptr) kGlobalScope = nullptr;
     318             : const uint64_t kNoId = 0;
     319             : 
     320             : class TraceEventHelper {
     321             :  public:
     322             :   static v8::TracingController* GetTracingController();
     323             : };
     324             : 
     325             : // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
     326             : // are by default mangled with the Process ID so that they are unlikely to
     327             : // collide when the same pointer is used on different processes.
     328             : class TraceID {
     329             :  public:
     330             :   class WithScope {
     331             :    public:
     332             :     WithScope(const char* scope, uint64_t raw_id)
     333             :         : scope_(scope), raw_id_(raw_id) {}
     334             :     uint64_t raw_id() const { return raw_id_; }
     335             :     const char* scope() const { return scope_; }
     336             : 
     337             :    private:
     338             :     const char* scope_ = nullptr;
     339             :     uint64_t raw_id_;
     340             :   };
     341             : 
     342             :   class DontMangle {
     343             :    public:
     344             :     explicit DontMangle(const void* raw_id)
     345             :         : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
     346             :     explicit DontMangle(uint64_t raw_id) : raw_id_(raw_id) {}
     347             :     explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {}
     348             :     explicit DontMangle(uint16_t raw_id) : raw_id_(raw_id) {}
     349             :     explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {}
     350             :     explicit DontMangle(int64_t raw_id)
     351             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     352             :     explicit DontMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
     353             :     explicit DontMangle(int16_t raw_id)
     354             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     355             :     explicit DontMangle(signed char raw_id)
     356             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     357             :     explicit DontMangle(WithScope scoped_id)
     358             :         : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
     359             :     const char* scope() const { return scope_; }
     360             :     uint64_t raw_id() const { return raw_id_; }
     361             : 
     362             :    private:
     363             :     const char* scope_ = nullptr;
     364             :     uint64_t raw_id_;
     365             :   };
     366             : 
     367             :   class ForceMangle {
     368             :    public:
     369             :     explicit ForceMangle(uint64_t raw_id) : raw_id_(raw_id) {}
     370             :     explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {}
     371             :     explicit ForceMangle(uint16_t raw_id) : raw_id_(raw_id) {}
     372             :     explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {}
     373             :     explicit ForceMangle(int64_t raw_id)
     374             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     375             :     explicit ForceMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
     376             :     explicit ForceMangle(int16_t raw_id)
     377             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     378             :     explicit ForceMangle(signed char raw_id)
     379             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     380             :     uint64_t raw_id() const { return raw_id_; }
     381             : 
     382             :    private:
     383             :     uint64_t raw_id_;
     384             :   };
     385             : 
     386             :   TraceID(const void* raw_id, unsigned int* flags)
     387             :       : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
     388             :     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
     389             :   }
     390             :   TraceID(ForceMangle raw_id, unsigned int* flags) : raw_id_(raw_id.raw_id()) {
     391             :     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
     392             :   }
     393             :   TraceID(DontMangle maybe_scoped_id, unsigned int* flags)
     394             :       : scope_(maybe_scoped_id.scope()), raw_id_(maybe_scoped_id.raw_id()) {}
     395             :   TraceID(uint64_t raw_id, unsigned int* flags) : raw_id_(raw_id) {
     396             :     (void)flags;
     397             :   }
     398           0 :   TraceID(unsigned int raw_id, unsigned int* flags) : raw_id_(raw_id) {
     399             :     (void)flags;
     400             :   }
     401             :   TraceID(uint16_t raw_id, unsigned int* flags) : raw_id_(raw_id) {
     402             :     (void)flags;
     403             :   }
     404             :   TraceID(unsigned char raw_id, unsigned int* flags) : raw_id_(raw_id) {
     405             :     (void)flags;
     406             :   }
     407             :   TraceID(int64_t raw_id, unsigned int* flags)
     408             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     409             :     (void)flags;
     410             :   }
     411             :   TraceID(int raw_id, unsigned int* flags)
     412             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     413             :     (void)flags;
     414             :   }
     415             :   TraceID(int16_t raw_id, unsigned int* flags)
     416             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     417             :     (void)flags;
     418             :   }
     419             :   TraceID(signed char raw_id, unsigned int* flags)
     420             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     421             :     (void)flags;
     422             :   }
     423             :   TraceID(WithScope scoped_id, unsigned int* flags)
     424             :       : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
     425             : 
     426             :   uint64_t raw_id() const { return raw_id_; }
     427             :   const char* scope() const { return scope_; }
     428             : 
     429             :  private:
     430             :   const char* scope_ = nullptr;
     431             :   uint64_t raw_id_;
     432             : };
     433             : 
     434             : // Simple union to store various types as uint64_t.
     435             : union TraceValueUnion {
     436             :   bool as_bool;
     437             :   uint64_t as_uint;
     438             :   int64_t as_int;
     439             :   double as_double;
     440             :   const void* as_pointer;
     441             :   const char* as_string;
     442             : };
     443             : 
     444             : // Simple container for const char* that should be copied instead of retained.
     445             : class TraceStringWithCopy {
     446             :  public:
     447          15 :   explicit TraceStringWithCopy(const char* str) : str_(str) {}
     448          15 :   operator const char*() const { return str_; }
     449             : 
     450             :  private:
     451             :   const char* str_;
     452             : };
     453             : 
     454             : static V8_INLINE uint64_t AddTraceEventImpl(
     455             :     char phase, const uint8_t* category_group_enabled, const char* name,
     456             :     const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
     457             :     const char** arg_names, const uint8_t* arg_types,
     458             :     const uint64_t* arg_values, unsigned int flags) {
     459        1020 :   std::unique_ptr<ConvertableToTraceFormat> arg_convertables[2];
     460         180 :   if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
     461             :     arg_convertables[0].reset(reinterpret_cast<ConvertableToTraceFormat*>(
     462          25 :         static_cast<intptr_t>(arg_values[0])));
     463             :   }
     464          55 :   if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) {
     465             :     arg_convertables[1].reset(reinterpret_cast<ConvertableToTraceFormat*>(
     466           5 :         static_cast<intptr_t>(arg_values[1])));
     467             :   }
     468             :   DCHECK_LE(num_args, 2);
     469             :   v8::TracingController* controller =
     470         255 :       v8::internal::tracing::TraceEventHelper::GetTracingController();
     471             :   return controller->AddTraceEvent(phase, category_group_enabled, name, scope,
     472             :                                    id, bind_id, num_args, arg_names, arg_types,
     473         255 :                                    arg_values, arg_convertables, flags);
     474             : }
     475             : 
     476             : static V8_INLINE uint64_t AddTraceEventWithTimestampImpl(
     477             :     char phase, const uint8_t* category_group_enabled, const char* name,
     478             :     const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
     479             :     const char** arg_names, const uint8_t* arg_types,
     480             :     const uint64_t* arg_values, unsigned int flags, int64_t timestamp) {
     481         100 :   std::unique_ptr<ConvertableToTraceFormat> arg_convertables[2];
     482          10 :   if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
     483             :     arg_convertables[0].reset(reinterpret_cast<ConvertableToTraceFormat*>(
     484           0 :         static_cast<intptr_t>(arg_values[0])));
     485             :   }
     486           5 :   if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) {
     487             :     arg_convertables[1].reset(reinterpret_cast<ConvertableToTraceFormat*>(
     488           0 :         static_cast<intptr_t>(arg_values[1])));
     489             :   }
     490             :   DCHECK_LE(num_args, 2);
     491             :   v8::TracingController* controller =
     492          25 :       v8::internal::tracing::TraceEventHelper::GetTracingController();
     493             :   return controller->AddTraceEventWithTimestamp(
     494             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     495          25 :       arg_names, arg_types, arg_values, arg_convertables, flags, timestamp);
     496             : }
     497             : 
     498             : // Define SetTraceValue for each allowed type. It stores the type and
     499             : // value in the return arguments. This allows this API to avoid declaring any
     500             : // structures so that it is portable to third_party libraries.
     501             : #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member,         \
     502             :                                          value_type_id)                     \
     503             :   static V8_INLINE void SetTraceValue(actual_type arg, unsigned char* type, \
     504             :                                       uint64_t* value) {                    \
     505             :     TraceValueUnion type_value;                                             \
     506             :     type_value.union_member = arg;                                          \
     507             :     *type = value_type_id;                                                  \
     508             :     *value = type_value.as_uint;                                            \
     509             :   }
     510             : // Simpler form for int types that can be safely casted.
     511             : #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id)    \
     512             :   static V8_INLINE void SetTraceValue(actual_type arg, unsigned char* type, \
     513             :                                       uint64_t* value) {                    \
     514             :     *type = value_type_id;                                                  \
     515             :     *value = static_cast<uint64_t>(arg);                                    \
     516             :   }
     517             : 
     518          10 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint64_t, TRACE_VALUE_TYPE_UINT)
     519           5 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
     520           5 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint16_t, TRACE_VALUE_TYPE_UINT)
     521           5 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
     522           5 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int64_t, TRACE_VALUE_TYPE_INT)
     523          55 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
     524           5 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int16_t, TRACE_VALUE_TYPE_INT)
     525           5 : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
     526          10 : INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL)
     527          25 : INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE)
     528           5 : INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
     529             :                                  TRACE_VALUE_TYPE_POINTER)
     530          60 : INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string,
     531             :                                  TRACE_VALUE_TYPE_STRING)
     532          15 : INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string,
     533             :                                  TRACE_VALUE_TYPE_COPY_STRING)
     534             : 
     535             : #undef INTERNAL_DECLARE_SET_TRACE_VALUE
     536             : #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
     537             : 
     538             : static V8_INLINE void SetTraceValue(ConvertableToTraceFormat* convertable_value,
     539             :                                     unsigned char* type, uint64_t* value) {
     540          30 :   *type = TRACE_VALUE_TYPE_CONVERTABLE;
     541          30 :   *value = static_cast<uint64_t>(reinterpret_cast<intptr_t>(convertable_value));
     542             : }
     543             : 
     544             : template <typename T>
     545             : static V8_INLINE typename std::enable_if<
     546             :     std::is_convertible<T*, ConvertableToTraceFormat*>::value>::type
     547             : SetTraceValue(std::unique_ptr<T> ptr, unsigned char* type, uint64_t* value) {
     548          20 :   SetTraceValue(ptr.release(), type, value);
     549             : }
     550             : 
     551             : // These AddTraceEvent template
     552             : // function is defined here instead of in the macro, because the arg_values
     553             : // could be temporary objects, such as std::string. In order to store
     554             : // pointers to the internal c_str and pass through to the tracing API,
     555             : // the arg_values must live throughout these procedures.
     556             : 
     557             : static V8_INLINE uint64_t AddTraceEvent(char phase,
     558             :                                         const uint8_t* category_group_enabled,
     559             :                                         const char* name, const char* scope,
     560             :                                         uint64_t id, uint64_t bind_id,
     561             :                                         unsigned int flags) {
     562             :   return TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name,
     563             :                                          scope, id, bind_id, kZeroNumArgs,
     564             :                                          nullptr, nullptr, nullptr, flags);
     565             : }
     566             : 
     567             : template <class ARG1_TYPE>
     568             : static V8_INLINE uint64_t AddTraceEvent(
     569             :     char phase, const uint8_t* category_group_enabled, const char* name,
     570             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     571             :     const char* arg1_name, ARG1_TYPE&& arg1_val) {
     572             :   const int num_args = 1;
     573             :   uint8_t arg_type;
     574             :   uint64_t arg_value;
     575         130 :   SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value);
     576             :   return TRACE_EVENT_API_ADD_TRACE_EVENT(
     577             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     578             :       &arg1_name, &arg_type, &arg_value, flags);
     579             : }
     580             : 
     581             : template <class ARG1_TYPE, class ARG2_TYPE>
     582             : static V8_INLINE uint64_t AddTraceEvent(
     583             :     char phase, const uint8_t* category_group_enabled, const char* name,
     584             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     585             :     const char* arg1_name, ARG1_TYPE&& arg1_val, const char* arg2_name,
     586             :     ARG2_TYPE&& arg2_val) {
     587             :   const int num_args = 2;
     588          45 :   const char* arg_names[2] = {arg1_name, arg2_name};
     589             :   unsigned char arg_types[2];
     590             :   uint64_t arg_values[2];
     591          45 :   SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0],
     592          30 :                 &arg_values[0]);
     593          45 :   SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1],
     594          30 :                 &arg_values[1]);
     595             :   return TRACE_EVENT_API_ADD_TRACE_EVENT(
     596             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     597             :       arg_names, arg_types, arg_values, flags);
     598             : }
     599             : 
     600             : static V8_INLINE uint64_t AddTraceEventWithTimestamp(
     601             :     char phase, const uint8_t* category_group_enabled, const char* name,
     602             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     603             :     int64_t timestamp) {
     604             :   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
     605             :       phase, category_group_enabled, name, scope, id, bind_id, kZeroNumArgs,
     606             :       nullptr, nullptr, nullptr, flags, timestamp);
     607             : }
     608             : 
     609             : template <class ARG1_TYPE>
     610             : static V8_INLINE uint64_t AddTraceEventWithTimestamp(
     611             :     char phase, const uint8_t* category_group_enabled, const char* name,
     612             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     613             :     int64_t timestamp, const char* arg1_name, ARG1_TYPE&& arg1_val) {
     614             :   const int num_args = 1;
     615             :   uint8_t arg_type;
     616             :   uint64_t arg_value;
     617           5 :   SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value);
     618             :   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
     619             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     620             :       &arg1_name, &arg_type, &arg_value, flags, timestamp);
     621             : }
     622             : 
     623             : template <class ARG1_TYPE, class ARG2_TYPE>
     624             : static V8_INLINE uint64_t AddTraceEventWithTimestamp(
     625             :     char phase, const uint8_t* category_group_enabled, const char* name,
     626             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     627             :     int64_t timestamp, const char* arg1_name, ARG1_TYPE&& arg1_val,
     628             :     const char* arg2_name, ARG2_TYPE&& arg2_val) {
     629             :   const int num_args = 2;
     630           5 :   const char* arg_names[2] = {arg1_name, arg2_name};
     631             :   unsigned char arg_types[2];
     632             :   uint64_t arg_values[2];
     633           5 :   SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0],
     634           5 :                 &arg_values[0]);
     635           5 :   SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1],
     636           5 :                 &arg_values[1]);
     637             :   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
     638             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     639             :       arg_names, arg_types, arg_values, flags, timestamp);
     640             : }
     641             : 
     642             : // Used by TRACE_EVENTx macros. Do not use directly.
     643             : class ScopedTracer {
     644             :  public:
     645             :   // Note: members of data_ intentionally left uninitialized. See Initialize.
     646    29973672 :   ScopedTracer() : p_data_(nullptr) {}
     647             : 
     648    29972838 :   ~ScopedTracer() {
     649    29972838 :     if (p_data_ && *data_.category_group_enabled)
     650          35 :       TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
     651          35 :           data_.category_group_enabled, data_.name, data_.event_handle);
     652    29972838 :   }
     653             : 
     654           0 :   void Initialize(const uint8_t* category_group_enabled, const char* name,
     655             :                   uint64_t event_handle) {
     656         145 :     data_.category_group_enabled = category_group_enabled;
     657         145 :     data_.name = name;
     658         145 :     data_.event_handle = event_handle;
     659         145 :     p_data_ = &data_;
     660           0 :   }
     661             : 
     662             :  private:
     663             :   // This Data struct workaround is to avoid initializing all the members
     664             :   // in Data during construction of this object, since this object is always
     665             :   // constructed, even when tracing is disabled. If the members of Data were
     666             :   // members of this class instead, compiler warnings occur about potential
     667             :   // uninitialized accesses.
     668             :   struct Data {
     669             :     const uint8_t* category_group_enabled;
     670             :     const char* name;
     671             :     uint64_t event_handle;
     672             :   };
     673             :   Data* p_data_;
     674             :   Data data_;
     675             : };
     676             : 
     677             : // Do not use directly.
     678             : class CallStatsScopedTracer {
     679             :  public:
     680     1099777 :   CallStatsScopedTracer() : p_data_(nullptr) {}
     681     1099774 :   ~CallStatsScopedTracer() {
     682     1099774 :     if (V8_UNLIKELY(p_data_ && *data_.category_group_enabled)) {
     683           5 :       AddEndTraceEvent();
     684             :     }
     685     1099774 :   }
     686             : 
     687             :   void Initialize(v8::internal::Isolate* isolate,
     688             :                   const uint8_t* category_group_enabled, const char* name);
     689             : 
     690             :  private:
     691             :   void AddEndTraceEvent();
     692             :   struct Data {
     693             :     const uint8_t* category_group_enabled;
     694             :     const char* name;
     695             :     v8::internal::Isolate* isolate;
     696             :   };
     697             :   bool has_parent_scope_;
     698             :   Data* p_data_;
     699             :   Data data_;
     700             : };
     701             : 
     702             : }  // namespace tracing
     703             : }  // namespace internal
     704             : }  // namespace v8
     705             : 
     706             : #endif  // V8_TRACING_TRACE_EVENT_H_

Generated by: LCOV version 1.10