LCOV - code coverage report
Current view: top level - src/tracing - trace-event.h (source / functions) Hit Total Coverage
Test: app.info Lines: 18 35 51.4 %
Date: 2017-04-26 Functions: 3 5 60.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 SRC_TRACING_TRACE_EVENT_H_
       6             : #define SRC_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             :   *INTERNAL_TRACE_EVENT_UID(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::GetCurrentPlatform() \
      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             : // Set the duration field of a COMPLETE trace event.
     100             : // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
     101             : //     const uint8_t* category_group_enabled,
     102             : //     const char* name,
     103             : //     uint64_t id)
     104             : #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION             \
     105             :   v8::internal::tracing::TraceEventHelper::GetCurrentPlatform() \
     106             :       ->UpdateTraceEventDuration
     107             : 
     108             : // Defines atomic operations used internally by the tracing system.
     109             : #define TRACE_EVENT_API_ATOMIC_WORD v8::base::AtomicWord
     110             : #define TRACE_EVENT_API_ATOMIC_LOAD(var) v8::base::NoBarrier_Load(&(var))
     111             : #define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
     112             :   v8::base::NoBarrier_Store(&(var), (value))
     113             : 
     114             : ////////////////////////////////////////////////////////////////////////////////
     115             : 
     116             : // Implementation detail: trace event macros create temporary variables
     117             : // to keep instrumentation overhead low. These macros give each temporary
     118             : // variable a unique name based on the line number to prevent name collisions.
     119             : #define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b
     120             : #define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b)
     121             : #define INTERNAL_TRACE_EVENT_UID(name_prefix) \
     122             :   INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
     123             : 
     124             : // Implementation detail: internal macro to create static category.
     125             : // No barriers are needed, because this code is designed to operate safely
     126             : // even when the unsigned char* points to garbage data (which may be the case
     127             : // on processors without cache coherency).
     128             : // TODO(fmeawad): This implementation contradicts that we can have a different
     129             : // configuration for each isolate,
     130             : // https://code.google.com/p/v8/issues/detail?id=4563
     131             : #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(             \
     132             :     category_group, atomic, category_group_enabled)                          \
     133             :   category_group_enabled =                                                   \
     134             :       reinterpret_cast<const uint8_t*>(TRACE_EVENT_API_ATOMIC_LOAD(atomic)); \
     135             :   if (!category_group_enabled) {                                             \
     136             :     category_group_enabled =                                                 \
     137             :         TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);          \
     138             :     TRACE_EVENT_API_ATOMIC_STORE(                                            \
     139             :         atomic, reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(               \
     140             :                     category_group_enabled));                                \
     141             :   }
     142             : 
     143             : #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group)             \
     144             :   static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
     145             :   const uint8_t* INTERNAL_TRACE_EVENT_UID(category_group_enabled);         \
     146             :   INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(                 \
     147             :       category_group, INTERNAL_TRACE_EVENT_UID(atomic),                    \
     148             :       INTERNAL_TRACE_EVENT_UID(category_group_enabled));
     149             : 
     150             : // Implementation detail: internal macro to create static category and add
     151             : // event if the category is enabled.
     152             : #define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...)    \
     153             :   do {                                                                       \
     154             :     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                  \
     155             :     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {  \
     156             :       v8::internal::tracing::AddTraceEvent(                                  \
     157             :           phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,     \
     158             :           v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \
     159             :           v8::internal::tracing::kNoId, flags, ##__VA_ARGS__);               \
     160             :     }                                                                        \
     161             :   } while (0)
     162             : 
     163             : // Implementation detail: internal macro to create static category and add begin
     164             : // event if the category is enabled. Also adds the end event when the scope
     165             : // ends.
     166             : #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...)           \
     167             :   INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                    \
     168             :   v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer);      \
     169             :   if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {    \
     170             :     uint64_t h = v8::internal::tracing::AddTraceEvent(                       \
     171             :         TRACE_EVENT_PHASE_COMPLETE,                                          \
     172             :         INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,              \
     173             :         v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId,   \
     174             :         v8::internal::tracing::kNoId, TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
     175             :     INTERNAL_TRACE_EVENT_UID(tracer)                                         \
     176             :         .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,  \
     177             :                     h);                                                      \
     178             :   }
     179             : 
     180             : #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name,     \
     181             :                                                   bind_id, flow_flags, ...) \
     182             :   INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                   \
     183             :   v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer);     \
     184             :   if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {   \
     185             :     unsigned int trace_event_flags = flow_flags;                            \
     186             :     v8::internal::tracing::TraceID trace_event_bind_id(bind_id,             \
     187             :                                                        &trace_event_flags); \
     188             :     uint64_t h = v8::internal::tracing::AddTraceEvent(                      \
     189             :         TRACE_EVENT_PHASE_COMPLETE,                                         \
     190             :         INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,             \
     191             :         v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId,  \
     192             :         trace_event_bind_id.raw_id(), trace_event_flags, ##__VA_ARGS__);    \
     193             :     INTERNAL_TRACE_EVENT_UID(tracer)                                        \
     194             :         .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
     195             :                     h);                                                     \
     196             :   }
     197             : 
     198             : // Implementation detail: internal macro to create static category and add
     199             : // event if the category is enabled.
     200             : #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id,      \
     201             :                                          flags, ...)                           \
     202             :   do {                                                                         \
     203             :     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                    \
     204             :     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {    \
     205             :       unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID;        \
     206             :       v8::internal::tracing::TraceID trace_event_trace_id(id,                  \
     207             :                                                           &trace_event_flags); \
     208             :       v8::internal::tracing::AddTraceEvent(                                    \
     209             :           phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,       \
     210             :           trace_event_trace_id.scope(), trace_event_trace_id.raw_id(),         \
     211             :           v8::internal::tracing::kNoId, trace_event_flags, ##__VA_ARGS__);     \
     212             :     }                                                                          \
     213             :   } while (0)
     214             : 
     215             : // Adds a trace event with a given timestamp. Not Implemented.
     216             : #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
     217             :                                                 timestamp, flags, ...)       \
     218             :   UNIMPLEMENTED()
     219             : 
     220             : // Adds a trace event with a given id and timestamp. Not Implemented.
     221             : #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP(     \
     222             :     phase, category_group, name, id, timestamp, flags, ...) \
     223             :   UNIMPLEMENTED()
     224             : 
     225             : // Adds a trace event with a given id, thread_id, and timestamp. Not
     226             : // Implemented.
     227             : #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
     228             :     phase, category_group, name, id, thread_id, timestamp, flags, ...) \
     229             :   UNIMPLEMENTED()
     230             : 
     231             : // Enter and leave a context based on the current scope.
     232             : #define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \
     233             :   struct INTERNAL_TRACE_EVENT_UID(ScopedContext) {                         \
     234             :    public:                                                                 \
     235             :     INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) {    \
     236             :       TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_);               \
     237             :     }                                                                      \
     238             :     ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() {                           \
     239             :       TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_);               \
     240             :     }                                                                      \
     241             :                                                                            \
     242             :    private:                                                                \
     243             :     /* Local class friendly DISALLOW_COPY_AND_ASSIGN */                    \
     244             :     INTERNAL_TRACE_EVENT_UID(ScopedContext)                                \
     245             :     (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}                    \
     246             :     void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}      \
     247             :     uint64_t cid_;                                                         \
     248             :   };                                                                       \
     249             :   INTERNAL_TRACE_EVENT_UID(ScopedContext)                                  \
     250             :   INTERNAL_TRACE_EVENT_UID(scoped_context)(context);
     251             : 
     252             : #define TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name) \
     253             :   INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name)
     254             : 
     255             : #define INTERNAL_TRACE_EVENT_CALL_STATS_SCOPED(isolate, category_group, name)  \
     256             :   INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                      \
     257             :   v8::internal::tracing::CallStatsScopedTracer INTERNAL_TRACE_EVENT_UID(       \
     258             :       tracer);                                                                 \
     259             :   if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {      \
     260             :     INTERNAL_TRACE_EVENT_UID(tracer)                                           \
     261             :         .Initialize(isolate, INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
     262             :                     name);                                                     \
     263             :   }
     264             : 
     265             : namespace v8 {
     266             : namespace internal {
     267             : 
     268             : class Isolate;
     269             : 
     270             : namespace tracing {
     271             : 
     272             : // Specify these values when the corresponding argument of AddTraceEvent is not
     273             : // used.
     274             : const int kZeroNumArgs = 0;
     275             : const decltype(nullptr) kGlobalScope = nullptr;
     276             : const uint64_t kNoId = 0;
     277             : 
     278             : class TraceEventHelper {
     279             :  public:
     280             :   static v8::Platform* GetCurrentPlatform();
     281             : };
     282             : 
     283             : // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
     284             : // are by default mangled with the Process ID so that they are unlikely to
     285             : // collide when the same pointer is used on different processes.
     286             : class TraceID {
     287             :  public:
     288             :   class WithScope {
     289             :    public:
     290             :     WithScope(const char* scope, uint64_t raw_id)
     291             :         : scope_(scope), raw_id_(raw_id) {}
     292             :     uint64_t raw_id() const { return raw_id_; }
     293             :     const char* scope() const { return scope_; }
     294             : 
     295             :    private:
     296             :     const char* scope_ = nullptr;
     297             :     uint64_t raw_id_;
     298             :   };
     299             : 
     300             :   class DontMangle {
     301             :    public:
     302             :     explicit DontMangle(const void* raw_id)
     303             :         : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
     304             :     explicit DontMangle(uint64_t raw_id) : raw_id_(raw_id) {}
     305             :     explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {}
     306             :     explicit DontMangle(uint16_t raw_id) : raw_id_(raw_id) {}
     307             :     explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {}
     308             :     explicit DontMangle(int64_t raw_id)
     309             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     310             :     explicit DontMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
     311             :     explicit DontMangle(int16_t raw_id)
     312             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     313             :     explicit DontMangle(signed char raw_id)
     314             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     315             :     explicit DontMangle(WithScope scoped_id)
     316             :         : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
     317             :     const char* scope() const { return scope_; }
     318             :     uint64_t raw_id() const { return raw_id_; }
     319             : 
     320             :    private:
     321             :     const char* scope_ = nullptr;
     322             :     uint64_t raw_id_;
     323             :   };
     324             : 
     325             :   class ForceMangle {
     326             :    public:
     327             :     explicit ForceMangle(uint64_t raw_id) : raw_id_(raw_id) {}
     328             :     explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {}
     329             :     explicit ForceMangle(uint16_t raw_id) : raw_id_(raw_id) {}
     330             :     explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {}
     331             :     explicit ForceMangle(int64_t raw_id)
     332             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     333             :     explicit ForceMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
     334             :     explicit ForceMangle(int16_t raw_id)
     335             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     336             :     explicit ForceMangle(signed char raw_id)
     337             :         : raw_id_(static_cast<uint64_t>(raw_id)) {}
     338             :     uint64_t raw_id() const { return raw_id_; }
     339             : 
     340             :    private:
     341             :     uint64_t raw_id_;
     342             :   };
     343             : 
     344             :   TraceID(const void* raw_id, unsigned int* flags)
     345           6 :       : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
     346             :     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
     347             :   }
     348             :   TraceID(ForceMangle raw_id, unsigned int* flags) : raw_id_(raw_id.raw_id()) {
     349             :     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
     350             :   }
     351             :   TraceID(DontMangle maybe_scoped_id, unsigned int* flags)
     352             :       : scope_(maybe_scoped_id.scope()), raw_id_(maybe_scoped_id.raw_id()) {}
     353             :   TraceID(uint64_t raw_id, unsigned int* flags) : raw_id_(raw_id) {
     354             :     (void)flags;
     355             :   }
     356             :   TraceID(unsigned int raw_id, unsigned int* flags) : raw_id_(raw_id) {
     357             :     (void)flags;
     358             :   }
     359             :   TraceID(uint16_t raw_id, unsigned int* flags) : raw_id_(raw_id) {
     360             :     (void)flags;
     361             :   }
     362             :   TraceID(unsigned char raw_id, unsigned int* flags) : raw_id_(raw_id) {
     363             :     (void)flags;
     364             :   }
     365             :   TraceID(int64_t raw_id, unsigned int* flags)
     366             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     367             :     (void)flags;
     368             :   }
     369             :   TraceID(int raw_id, unsigned int* flags)
     370             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     371             :     (void)flags;
     372             :   }
     373             :   TraceID(int16_t raw_id, unsigned int* flags)
     374             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     375             :     (void)flags;
     376             :   }
     377             :   TraceID(signed char raw_id, unsigned int* flags)
     378             :       : raw_id_(static_cast<uint64_t>(raw_id)) {
     379             :     (void)flags;
     380             :   }
     381             :   TraceID(WithScope scoped_id, unsigned int* flags)
     382             :       : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
     383             : 
     384             :   uint64_t raw_id() const { return raw_id_; }
     385             :   const char* scope() const { return scope_; }
     386             : 
     387             :  private:
     388             :   const char* scope_ = nullptr;
     389             :   uint64_t raw_id_;
     390             : };
     391             : 
     392             : // Simple union to store various types as uint64_t.
     393             : union TraceValueUnion {
     394             :   bool as_bool;
     395             :   uint64_t as_uint;
     396             :   int64_t as_int;
     397             :   double as_double;
     398             :   const void* as_pointer;
     399             :   const char* as_string;
     400             : };
     401             : 
     402             : // Simple container for const char* that should be copied instead of retained.
     403             : class TraceStringWithCopy {
     404             :  public:
     405           0 :   explicit TraceStringWithCopy(const char* str) : str_(str) {}
     406           0 :   operator const char*() const { return str_; }
     407             : 
     408             :  private:
     409             :   const char* str_;
     410             : };
     411             : 
     412             : static V8_INLINE uint64_t AddTraceEventImpl(
     413             :     char phase, const uint8_t* category_group_enabled, const char* name,
     414             :     const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
     415             :     const char** arg_names, const uint8_t* arg_types,
     416             :     const uint64_t* arg_values, unsigned int flags) {
     417          24 :   std::unique_ptr<ConvertableToTraceFormat> arg_convertables[2];
     418           6 :   if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
     419             :     arg_convertables[0].reset(reinterpret_cast<ConvertableToTraceFormat*>(
     420           6 :         static_cast<intptr_t>(arg_values[0])));
     421             :   }
     422           0 :   if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) {
     423             :     arg_convertables[1].reset(reinterpret_cast<ConvertableToTraceFormat*>(
     424           0 :         static_cast<intptr_t>(arg_values[1])));
     425             :   }
     426             :   DCHECK(num_args <= 2);
     427             :   v8::Platform* platform =
     428           6 :       v8::internal::tracing::TraceEventHelper::GetCurrentPlatform();
     429             :   return platform->AddTraceEvent(phase, category_group_enabled, name, scope, id,
     430             :                                  bind_id, num_args, arg_names, arg_types,
     431           6 :                                  arg_values, arg_convertables, flags);
     432             : }
     433             : 
     434             : // Define SetTraceValue for each allowed type. It stores the type and
     435             : // value in the return arguments. This allows this API to avoid declaring any
     436             : // structures so that it is portable to third_party libraries.
     437             : #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member,         \
     438             :                                          value_type_id)                     \
     439             :   static V8_INLINE void SetTraceValue(actual_type arg, unsigned char* type, \
     440             :                                       uint64_t* value) {                    \
     441             :     TraceValueUnion type_value;                                             \
     442             :     type_value.union_member = arg;                                          \
     443             :     *type = value_type_id;                                                  \
     444             :     *value = type_value.as_uint;                                            \
     445             :   }
     446             : // Simpler form for int types that can be safely casted.
     447             : #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id)    \
     448             :   static V8_INLINE void SetTraceValue(actual_type arg, unsigned char* type, \
     449             :                                       uint64_t* value) {                    \
     450             :     *type = value_type_id;                                                  \
     451             :     *value = static_cast<uint64_t>(arg);                                    \
     452             :   }
     453             : 
     454             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint64_t, TRACE_VALUE_TYPE_UINT)
     455             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
     456             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint16_t, TRACE_VALUE_TYPE_UINT)
     457             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
     458             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int64_t, TRACE_VALUE_TYPE_INT)
     459             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
     460             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int16_t, TRACE_VALUE_TYPE_INT)
     461             : INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
     462             : INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL)
     463             : INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE)
     464             : INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
     465             :                                  TRACE_VALUE_TYPE_POINTER)
     466             : INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string,
     467             :                                  TRACE_VALUE_TYPE_STRING)
     468           0 : INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string,
     469             :                                  TRACE_VALUE_TYPE_COPY_STRING)
     470             : 
     471             : #undef INTERNAL_DECLARE_SET_TRACE_VALUE
     472             : #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
     473             : 
     474             : static V8_INLINE void SetTraceValue(ConvertableToTraceFormat* convertable_value,
     475             :                                     unsigned char* type, uint64_t* value) {
     476           6 :   *type = TRACE_VALUE_TYPE_CONVERTABLE;
     477           6 :   *value = static_cast<uint64_t>(reinterpret_cast<intptr_t>(convertable_value));
     478             : }
     479             : 
     480             : template <typename T>
     481             : static V8_INLINE typename std::enable_if<
     482             :     std::is_convertible<T*, ConvertableToTraceFormat*>::value>::type
     483             : SetTraceValue(std::unique_ptr<T> ptr, unsigned char* type, uint64_t* value) {
     484           6 :   SetTraceValue(ptr.release(), type, value);
     485             : }
     486             : 
     487             : // These AddTraceEvent template
     488             : // function is defined here instead of in the macro, because the arg_values
     489             : // could be temporary objects, such as std::string. In order to store
     490             : // pointers to the internal c_str and pass through to the tracing API,
     491             : // the arg_values must live throughout these procedures.
     492             : 
     493             : static V8_INLINE uint64_t AddTraceEvent(char phase,
     494             :                                         const uint8_t* category_group_enabled,
     495             :                                         const char* name, const char* scope,
     496             :                                         uint64_t id, uint64_t bind_id,
     497             :                                         unsigned int flags) {
     498             :   return TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name,
     499             :                                          scope, id, bind_id, kZeroNumArgs,
     500             :                                          nullptr, nullptr, nullptr, flags);
     501             : }
     502             : 
     503             : template <class ARG1_TYPE>
     504             : static V8_INLINE uint64_t AddTraceEvent(
     505             :     char phase, const uint8_t* category_group_enabled, const char* name,
     506             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     507             :     const char* arg1_name, ARG1_TYPE&& arg1_val) {
     508             :   const int num_args = 1;
     509             :   uint8_t arg_type;
     510             :   uint64_t arg_value;
     511          12 :   SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value);
     512             :   return TRACE_EVENT_API_ADD_TRACE_EVENT(
     513             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     514             :       &arg1_name, &arg_type, &arg_value, flags);
     515             : }
     516             : 
     517             : template <class ARG1_TYPE, class ARG2_TYPE>
     518             : static V8_INLINE uint64_t AddTraceEvent(
     519             :     char phase, const uint8_t* category_group_enabled, const char* name,
     520             :     const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags,
     521             :     const char* arg1_name, ARG1_TYPE&& arg1_val, const char* arg2_name,
     522             :     ARG2_TYPE&& arg2_val) {
     523             :   const int num_args = 2;
     524           0 :   const char* arg_names[2] = {arg1_name, arg2_name};
     525             :   unsigned char arg_types[2];
     526             :   uint64_t arg_values[2];
     527           0 :   SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0],
     528             :                 &arg_values[0]);
     529           0 :   SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1],
     530             :                 &arg_values[1]);
     531             :   return TRACE_EVENT_API_ADD_TRACE_EVENT(
     532             :       phase, category_group_enabled, name, scope, id, bind_id, num_args,
     533             :       arg_names, arg_types, arg_values, flags);
     534             : }
     535             : 
     536             : // Used by TRACE_EVENTx macros. Do not use directly.
     537             : class ScopedTracer {
     538             :  public:
     539             :   // Note: members of data_ intentionally left uninitialized. See Initialize.
     540    19518853 :   ScopedTracer() : p_data_(NULL) {}
     541             : 
     542    19518843 :   ~ScopedTracer() {
     543    19518843 :     if (p_data_ && *data_.category_group_enabled)
     544           0 :       TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
     545           0 :           data_.category_group_enabled, data_.name, data_.event_handle);
     546    19518843 :   }
     547             : 
     548           0 :   void Initialize(const uint8_t* category_group_enabled, const char* name,
     549             :                   uint64_t event_handle) {
     550           0 :     data_.category_group_enabled = category_group_enabled;
     551           0 :     data_.name = name;
     552           0 :     data_.event_handle = event_handle;
     553           0 :     p_data_ = &data_;
     554           0 :   }
     555             : 
     556             :  private:
     557             :   // This Data struct workaround is to avoid initializing all the members
     558             :   // in Data during construction of this object, since this object is always
     559             :   // constructed, even when tracing is disabled. If the members of Data were
     560             :   // members of this class instead, compiler warnings occur about potential
     561             :   // uninitialized accesses.
     562             :   struct Data {
     563             :     const uint8_t* category_group_enabled;
     564             :     const char* name;
     565             :     uint64_t event_handle;
     566             :   };
     567             :   Data* p_data_;
     568             :   Data data_;
     569             : };
     570             : 
     571             : // Do not use directly.
     572             : class CallStatsScopedTracer {
     573             :  public:
     574    30484940 :   CallStatsScopedTracer() : p_data_(nullptr) {}
     575    30484934 :   ~CallStatsScopedTracer() {
     576    30484934 :     if (V8_UNLIKELY(p_data_ && *data_.category_group_enabled)) {
     577           0 :       AddEndTraceEvent();
     578             :     }
     579    30484934 :   }
     580             : 
     581             :   void Initialize(v8::internal::Isolate* isolate,
     582             :                   const uint8_t* category_group_enabled, const char* name);
     583             : 
     584             :  private:
     585             :   void AddEndTraceEvent();
     586             :   struct Data {
     587             :     const uint8_t* category_group_enabled;
     588             :     const char* name;
     589             :     v8::internal::Isolate* isolate;
     590             :   };
     591             :   bool has_parent_scope_;
     592             :   Data* p_data_;
     593             :   Data data_;
     594             : };
     595             : 
     596             : }  // namespace tracing
     597             : }  // namespace internal
     598             : }  // namespace v8
     599             : 
     600             : #endif  // SRC_TRACING_TRACE_EVENT_H_

Generated by: LCOV version 1.10