Home | History | Annotate | Download | only in trace_event
      1 // Copyright (c) 2012 The Chromium 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 BASE_TRACE_EVENT_TRACE_EVENT_H_
      6 #define BASE_TRACE_EVENT_TRACE_EVENT_H_
      7 
      8 // This header file defines implementation details of how the trace macros in
      9 // trace_event_common.h collect and store trace events. Anything not
     10 // implementation-specific should go in trace_event_common.h instead of here.
     11 
     12 #include <stddef.h>
     13 #include <stdint.h>
     14 
     15 #include <string>
     16 
     17 #include "base/atomicops.h"
     18 #include "base/macros.h"
     19 #include "base/time/time.h"
     20 #include "base/trace_event/common/trace_event_common.h"
     21 #include "base/trace_event/heap_profiler.h"
     22 #include "base/trace_event/trace_event_system_stats_monitor.h"
     23 #include "base/trace_event/trace_log.h"
     24 #include "build/build_config.h"
     25 
     26 // By default, const char* argument values are assumed to have long-lived scope
     27 // and will not be copied. Use this macro to force a const char* to be copied.
     28 #define TRACE_STR_COPY(str) \
     29     trace_event_internal::TraceStringWithCopy(str)
     30 
     31 // By default, uint64_t ID argument values are not mangled with the Process ID
     32 // in TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
     33 #define TRACE_ID_MANGLE(id) \
     34     trace_event_internal::TraceID::ForceMangle(id)
     35 
     36 // By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
     37 // macros. Use this macro to prevent Process ID mangling.
     38 #define TRACE_ID_DONT_MANGLE(id) \
     39     trace_event_internal::TraceID::DontMangle(id)
     40 
     41 // By default, trace IDs are eventually converted to a single 64-bit number. Use
     42 // this macro to add a scope string.
     43 #define TRACE_ID_WITH_SCOPE(scope, id) \
     44     trace_event_internal::TraceID::WithScope(scope, id)
     45 
     46 // Sets the current sample state to the given category and name (both must be
     47 // constant strings). These states are intended for a sampling profiler.
     48 // Implementation note: we store category and name together because we don't
     49 // want the inconsistency/expense of storing two pointers.
     50 // |thread_bucket| is [0..2] and is used to statically isolate samples in one
     51 // thread from others.
     52 #define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET( \
     53     bucket_number, category, name)                 \
     54         trace_event_internal::                     \
     55         TraceEventSamplingStateScope<bucket_number>::Set(category "\0" name)
     56 
     57 // Returns a current sampling state of the given bucket.
     58 #define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
     59     trace_event_internal::TraceEventSamplingStateScope<bucket_number>::Current()
     60 
     61 // Creates a scope of a sampling state of the given bucket.
     62 //
     63 // {  // The sampling state is set within this scope.
     64 //    TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
     65 //    ...;
     66 // }
     67 #define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(                   \
     68     bucket_number, category, name)                                      \
     69     trace_event_internal::TraceEventSamplingStateScope<bucket_number>   \
     70         traceEventSamplingScope(category "\0" name);
     71 
     72 #define TRACE_EVENT_API_CURRENT_THREAD_ID \
     73   static_cast<int>(base::PlatformThread::CurrentId())
     74 
     75 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
     76   UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) &           \
     77            (base::trace_event::TraceLog::ENABLED_FOR_RECORDING |         \
     78             base::trace_event::TraceLog::ENABLED_FOR_EVENT_CALLBACK |    \
     79             base::trace_event::TraceLog::ENABLED_FOR_ETW_EXPORT))
     80 
     81 ////////////////////////////////////////////////////////////////////////////////
     82 // Implementation specific tracing API definitions.
     83 
     84 // Get a pointer to the enabled state of the given trace category. Only
     85 // long-lived literal strings should be given as the category group. The
     86 // returned pointer can be held permanently in a local static for example. If
     87 // the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
     88 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
     89 // between the load of the tracing state and the call to
     90 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
     91 // for best performance when tracing is disabled.
     92 // const unsigned char*
     93 //     TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
     94 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
     95     base::trace_event::TraceLog::GetCategoryGroupEnabled
     96 
     97 // Get the number of times traces have been recorded. This is used to implement
     98 // the TRACE_EVENT_IS_NEW_TRACE facility.
     99 // unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED()
    100 #define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED \
    101     base::trace_event::TraceLog::GetInstance()->GetNumTracesRecorded
    102 
    103 // Add a trace event to the platform tracing system.
    104 // base::trace_event::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT(
    105 //                    char phase,
    106 //                    const unsigned char* category_group_enabled,
    107 //                    const char* name,
    108 //                    const char* scope,
    109 //                    unsigned long long id,
    110 //                    int num_args,
    111 //                    const char** arg_names,
    112 //                    const unsigned char* arg_types,
    113 //                    const unsigned long long* arg_values,
    114 //                    std::unique_ptr<ConvertableToTraceFormat>*
    115 //                    convertable_values,
    116 //                    unsigned int flags)
    117 #define TRACE_EVENT_API_ADD_TRACE_EVENT \
    118     base::trace_event::TraceLog::GetInstance()->AddTraceEvent
    119 
    120 // Add a trace event to the platform tracing system.
    121 // base::trace_event::TraceEventHandle
    122 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID(
    123 //                    char phase,
    124 //                    const unsigned char* category_group_enabled,
    125 //                    const char* name,
    126 //                    const char* scope,
    127 //                    unsigned long long id,
    128 //                    unsigned long long bind_id,
    129 //                    int num_args,
    130 //                    const char** arg_names,
    131 //                    const unsigned char* arg_types,
    132 //                    const unsigned long long* arg_values,
    133 //                    std::unique_ptr<ConvertableToTraceFormat>*
    134 //                    convertable_values,
    135 //                    unsigned int flags)
    136 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID \
    137   base::trace_event::TraceLog::GetInstance()->AddTraceEventWithBindId
    138 
    139 // Add a trace event to the platform tracing system overriding the pid.
    140 // The resulting event will have tid = pid == (process_id passed here).
    141 // base::trace_event::TraceEventHandle
    142 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
    143 //                    char phase,
    144 //                    const unsigned char* category_group_enabled,
    145 //                    const char* name,
    146 //                    const char* scope,
    147 //                    unsigned long long id,
    148 //                    int process_id,
    149 //                    int num_args,
    150 //                    const char** arg_names,
    151 //                    const unsigned char* arg_types,
    152 //                    const unsigned long long* arg_values,
    153 //                    std::unique_ptr<ConvertableToTraceFormat>*
    154 //                    convertable_values,
    155 //                    unsigned int flags)
    156 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID \
    157   base::trace_event::TraceLog::GetInstance()->AddTraceEventWithProcessId
    158 
    159 // Add a trace event to the platform tracing system.
    160 // base::trace_event::TraceEventHandle
    161 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
    162 //                    char phase,
    163 //                    const unsigned char* category_group_enabled,
    164 //                    const char* name,
    165 //                    const char* scope,
    166 //                    unsigned long long id,
    167 //                    int thread_id,
    168 //                    const TimeTicks& timestamp,
    169 //                    int num_args,
    170 //                    const char** arg_names,
    171 //                    const unsigned char* arg_types,
    172 //                    const unsigned long long* arg_values,
    173 //                    std::unique_ptr<ConvertableToTraceFormat>*
    174 //                    convertable_values,
    175 //                    unsigned int flags)
    176 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \
    177     base::trace_event::TraceLog::GetInstance() \
    178       ->AddTraceEventWithThreadIdAndTimestamp
    179 
    180 // Set the duration field of a COMPLETE trace event.
    181 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
    182 //     const unsigned char* category_group_enabled,
    183 //     const char* name,
    184 //     base::trace_event::TraceEventHandle id)
    185 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
    186     base::trace_event::TraceLog::GetInstance()->UpdateTraceEventDuration
    187 
    188 // Adds a metadata event to the trace log. The |AppendValueAsTraceFormat| method
    189 // on the convertable value will be called at flush time.
    190 // TRACE_EVENT_API_ADD_METADATA_EVENT(
    191 //     const unsigned char* category_group_enabled,
    192 //     const char* event_name,
    193 //     const char* arg_name,
    194 //     std::unique_ptr<ConvertableToTraceFormat> arg_value)
    195 #define TRACE_EVENT_API_ADD_METADATA_EVENT \
    196     trace_event_internal::AddMetadataEvent
    197 
    198 // Defines atomic operations used internally by the tracing system.
    199 #define TRACE_EVENT_API_ATOMIC_WORD base::subtle::AtomicWord
    200 #define TRACE_EVENT_API_ATOMIC_LOAD(var) base::subtle::NoBarrier_Load(&(var))
    201 #define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
    202     base::subtle::NoBarrier_Store(&(var), (value))
    203 
    204 // Defines visibility for classes in trace_event.h
    205 #define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT
    206 
    207 // The thread buckets for the sampling profiler.
    208 TRACE_EVENT_API_CLASS_EXPORT extern \
    209     TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3];
    210 
    211 #define TRACE_EVENT_API_THREAD_BUCKET(thread_bucket)                           \
    212     g_trace_state[thread_bucket]
    213 
    214 ////////////////////////////////////////////////////////////////////////////////
    215 
    216 // Implementation detail: trace event macros create temporary variables
    217 // to keep instrumentation overhead low. These macros give each temporary
    218 // variable a unique name based on the line number to prevent name collisions.
    219 #define INTERNAL_TRACE_EVENT_UID3(a,b) \
    220     trace_event_unique_##a##b
    221 #define INTERNAL_TRACE_EVENT_UID2(a,b) \
    222     INTERNAL_TRACE_EVENT_UID3(a,b)
    223 #define INTERNAL_TRACE_EVENT_UID(name_prefix) \
    224     INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
    225 
    226 // Implementation detail: internal macro to create static category.
    227 // No barriers are needed, because this code is designed to operate safely
    228 // even when the unsigned char* points to garbage data (which may be the case
    229 // on processors without cache coherency).
    230 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
    231     category_group, atomic, category_group_enabled) \
    232     category_group_enabled = \
    233         reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \
    234             atomic)); \
    235     if (UNLIKELY(!category_group_enabled)) { \
    236       category_group_enabled = \
    237           TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
    238       TRACE_EVENT_API_ATOMIC_STORE(atomic, \
    239           reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
    240               category_group_enabled)); \
    241     }
    242 
    243 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
    244     static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
    245     const unsigned char* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
    246     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(category_group, \
    247         INTERNAL_TRACE_EVENT_UID(atomic), \
    248         INTERNAL_TRACE_EVENT_UID(category_group_enabled));
    249 
    250 // Implementation detail: internal macro to create static category and add
    251 // event if the category is enabled.
    252 #define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
    253     do { \
    254       INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
    255       if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
    256         trace_event_internal::AddTraceEvent( \
    257             phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
    258             trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
    259             flags, trace_event_internal::kNoId, ##__VA_ARGS__); \
    260       } \
    261     } while (0)
    262 
    263 // Implementation detail: internal macro to create static category and add begin
    264 // event if the category is enabled. Also adds the end event when the scope
    265 // ends.
    266 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
    267     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
    268     trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
    269     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
    270       base::trace_event::TraceEventHandle h = \
    271           trace_event_internal::AddTraceEvent( \
    272               TRACE_EVENT_PHASE_COMPLETE, \
    273               INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
    274               trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
    275               TRACE_EVENT_FLAG_NONE, trace_event_internal::kNoId, \
    276               ##__VA_ARGS__); \
    277       INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \
    278           INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \
    279     }
    280 
    281 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW( \
    282     category_group, name, bind_id, flow_flags, ...) \
    283   INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
    284   trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
    285   if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
    286     unsigned int trace_event_flags = flow_flags; \
    287     trace_event_internal::TraceID trace_event_bind_id(bind_id, \
    288                                                       &trace_event_flags); \
    289     base::trace_event::TraceEventHandle h = \
    290         trace_event_internal::AddTraceEvent( \
    291             TRACE_EVENT_PHASE_COMPLETE, \
    292             INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
    293             trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
    294             trace_event_flags, trace_event_bind_id.raw_id(), ##__VA_ARGS__); \
    295     INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \
    296         INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \
    297   }
    298 
    299 // Implementation detail: internal macro to create static category and add
    300 // event if the category is enabled.
    301 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \
    302                                          flags, ...) \
    303     do { \
    304       INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
    305       if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
    306         unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
    307         trace_event_internal::TraceID trace_event_trace_id( \
    308             id, &trace_event_flags); \
    309         trace_event_internal::AddTraceEvent( \
    310             phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
    311             name, trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
    312             trace_event_flags, trace_event_internal::kNoId, ##__VA_ARGS__); \
    313       } \
    314     } while (0)
    315 
    316 // Implementation detail: internal macro to create static category and add
    317 // event if the category is enabled.
    318 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
    319                                                 timestamp, flags, ...)       \
    320   do {                                                                       \
    321     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                  \
    322     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {  \
    323       trace_event_internal::AddTraceEventWithThreadIdAndTimestamp(           \
    324           phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,     \
    325           trace_event_internal::kGlobalScope, trace_event_internal::kNoId,   \
    326           TRACE_EVENT_API_CURRENT_THREAD_ID,                                 \
    327           base::TimeTicks::FromInternalValue(timestamp),                     \
    328           flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP,                       \
    329           trace_event_internal::kNoId, ##__VA_ARGS__);                       \
    330     }                                                                        \
    331   } while (0)
    332 
    333 // Implementation detail: internal macro to create static category and add
    334 // event if the category is enabled.
    335 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
    336     phase, category_group, name, id, thread_id, timestamp, flags, ...)        \
    337   do {                                                                        \
    338     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                   \
    339     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {   \
    340       unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID;       \
    341       trace_event_internal::TraceID trace_event_trace_id(id,                  \
    342                                                          &trace_event_flags); \
    343       trace_event_internal::AddTraceEventWithThreadIdAndTimestamp(            \
    344           phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,      \
    345           trace_event_trace_id.scope(), trace_event_trace_id.raw_id(),        \
    346           thread_id, base::TimeTicks::FromInternalValue(timestamp),           \
    347           trace_event_flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP,            \
    348           trace_event_internal::kNoId, ##__VA_ARGS__);                        \
    349     }                                                                         \
    350   } while (0)
    351 
    352 // Implementation detail: internal macro to create static category and add
    353 // metadata event if the category is enabled.
    354 #define INTERNAL_TRACE_EVENT_METADATA_ADD(category_group, name, ...)        \
    355   do {                                                                      \
    356     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                 \
    357     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
    358       TRACE_EVENT_API_ADD_METADATA_EVENT(                                   \
    359           INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,           \
    360           ##__VA_ARGS__);                                                   \
    361     }                                                                       \
    362   } while (0)
    363 
    364 // Implementation detail: internal macro to enter and leave a
    365 // context based on the current scope.
    366 #define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \
    367   struct INTERNAL_TRACE_EVENT_UID(ScopedContext) {                         \
    368    public:                                                                 \
    369     INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) {    \
    370       TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_);               \
    371     }                                                                      \
    372     ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() {                           \
    373       TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_);               \
    374     }                                                                      \
    375                                                                            \
    376    private:                                                                \
    377     uint64_t cid_;                                                         \
    378     /* Local class friendly DISALLOW_COPY_AND_ASSIGN */                    \
    379     INTERNAL_TRACE_EVENT_UID(ScopedContext)                                \
    380     (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {};                   \
    381     void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {};     \
    382   };                                                                       \
    383   INTERNAL_TRACE_EVENT_UID(ScopedContext)                                  \
    384   INTERNAL_TRACE_EVENT_UID(scoped_context)(context.raw_id());
    385 
    386 // Implementation detail: internal macro to trace a task execution with the
    387 // location where it was posted from.
    388 #define INTERNAL_TRACE_TASK_EXECUTION(run_function, task)                 \
    389   TRACE_EVENT2("toplevel", run_function, "src_file",                      \
    390                (task).posted_from.file_name(), "src_func",                \
    391                (task).posted_from.function_name());                       \
    392   TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION INTERNAL_TRACE_EVENT_UID( \
    393       task_event)((task).posted_from.file_name());
    394 
    395 namespace trace_event_internal {
    396 
    397 // Specify these values when the corresponding argument of AddTraceEvent is not
    398 // used.
    399 const int kZeroNumArgs = 0;
    400 const std::nullptr_t kGlobalScope = nullptr;
    401 const unsigned long long kNoId = 0;
    402 
    403 // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
    404 // are by default mangled with the Process ID so that they are unlikely to
    405 // collide when the same pointer is used on different processes.
    406 class TraceID {
    407  public:
    408   class WithScope {
    409    public:
    410     WithScope(const char* scope, unsigned long long raw_id)
    411         : scope_(scope), raw_id_(raw_id) {}
    412     unsigned long long raw_id() const { return raw_id_; }
    413     const char* scope() const { return scope_; }
    414    private:
    415     const char* scope_ = nullptr;
    416     unsigned long long raw_id_;
    417   };
    418 
    419   class DontMangle {
    420    public:
    421     explicit DontMangle(const void* raw_id)
    422         : raw_id_(static_cast<unsigned long long>(
    423               reinterpret_cast<uintptr_t>(raw_id))) {}
    424     explicit DontMangle(unsigned long long raw_id) : raw_id_(raw_id) {}
    425     explicit DontMangle(unsigned long raw_id) : raw_id_(raw_id) {}
    426     explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {}
    427     explicit DontMangle(unsigned short raw_id) : raw_id_(raw_id) {}
    428     explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {}
    429     explicit DontMangle(long long raw_id)
    430         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    431     explicit DontMangle(long raw_id)
    432         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    433     explicit DontMangle(int raw_id)
    434         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    435     explicit DontMangle(short raw_id)
    436         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    437     explicit DontMangle(signed char raw_id)
    438         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    439     explicit DontMangle(WithScope scoped_id)
    440         : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
    441     const char* scope() const { return scope_; }
    442     unsigned long long raw_id() const { return raw_id_; }
    443    private:
    444     const char* scope_ = nullptr;
    445     unsigned long long raw_id_;
    446   };
    447 
    448   class ForceMangle {
    449    public:
    450     explicit ForceMangle(unsigned long long raw_id) : raw_id_(raw_id) {}
    451     explicit ForceMangle(unsigned long raw_id) : raw_id_(raw_id) {}
    452     explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {}
    453     explicit ForceMangle(unsigned short raw_id) : raw_id_(raw_id) {}
    454     explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {}
    455     explicit ForceMangle(long long raw_id)
    456         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    457     explicit ForceMangle(long raw_id)
    458         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    459     explicit ForceMangle(int raw_id)
    460         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    461     explicit ForceMangle(short raw_id)
    462         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    463     explicit ForceMangle(signed char raw_id)
    464         : raw_id_(static_cast<unsigned long long>(raw_id)) {}
    465     unsigned long long raw_id() const { return raw_id_; }
    466    private:
    467     unsigned long long raw_id_;
    468   };
    469   TraceID(const void* raw_id, unsigned int* flags)
    470       : raw_id_(static_cast<unsigned long long>(
    471                 reinterpret_cast<uintptr_t>(raw_id))) {
    472     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
    473   }
    474   TraceID(ForceMangle raw_id, unsigned int* flags) : raw_id_(raw_id.raw_id()) {
    475     *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
    476   }
    477   TraceID(DontMangle maybe_scoped_id, unsigned int* /*flags*/)
    478       : scope_(maybe_scoped_id.scope()), raw_id_(maybe_scoped_id.raw_id()) {}
    479   TraceID(unsigned long long raw_id, unsigned int* flags) : raw_id_(raw_id) {
    480     (void)flags;
    481   }
    482   TraceID(unsigned long raw_id, unsigned int* flags) : raw_id_(raw_id) {
    483     (void)flags;
    484   }
    485   TraceID(unsigned int raw_id, unsigned int* flags) : raw_id_(raw_id) {
    486     (void)flags;
    487   }
    488   TraceID(unsigned short raw_id, unsigned int* flags) : raw_id_(raw_id) {
    489     (void)flags;
    490   }
    491   TraceID(unsigned char raw_id, unsigned int* flags) : raw_id_(raw_id) {
    492     (void)flags;
    493   }
    494   TraceID(long long raw_id, unsigned int* flags)
    495       : raw_id_(static_cast<unsigned long long>(raw_id)) { (void)flags; }
    496   TraceID(long raw_id, unsigned int* flags)
    497       : raw_id_(static_cast<unsigned long long>(raw_id)) { (void)flags; }
    498   TraceID(int raw_id, unsigned int* flags)
    499       : raw_id_(static_cast<unsigned long long>(raw_id)) { (void)flags; }
    500   TraceID(short raw_id, unsigned int* flags)
    501       : raw_id_(static_cast<unsigned long long>(raw_id)) { (void)flags; }
    502   TraceID(signed char raw_id, unsigned int* flags)
    503       : raw_id_(static_cast<unsigned long long>(raw_id)) { (void)flags; }
    504   TraceID(WithScope scoped_id, unsigned int* /*flags*/)
    505       : scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {}
    506 
    507   unsigned long long raw_id() const { return raw_id_; }
    508   const char* scope() const { return scope_; }
    509 
    510  private:
    511   const char* scope_ = nullptr;
    512   unsigned long long raw_id_;
    513 };
    514 
    515 // Simple union to store various types as unsigned long long.
    516 union TraceValueUnion {
    517   bool as_bool;
    518   unsigned long long as_uint;
    519   long long as_int;
    520   double as_double;
    521   const void* as_pointer;
    522   const char* as_string;
    523 };
    524 
    525 // Simple container for const char* that should be copied instead of retained.
    526 class TraceStringWithCopy {
    527  public:
    528   explicit TraceStringWithCopy(const char* str) : str_(str) {}
    529   const char* str() const { return str_; }
    530  private:
    531   const char* str_;
    532 };
    533 
    534 // Define SetTraceValue for each allowed type. It stores the type and
    535 // value in the return arguments. This allows this API to avoid declaring any
    536 // structures so that it is portable to third_party libraries.
    537 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
    538                                          arg_expression, \
    539                                          union_member, \
    540                                          value_type_id) \
    541     static inline void SetTraceValue( \
    542         actual_type arg, \
    543         unsigned char* type, \
    544         unsigned long long* value) { \
    545       TraceValueUnion type_value; \
    546       type_value.union_member = arg_expression; \
    547       *type = value_type_id; \
    548       *value = type_value.as_uint; \
    549     }
    550 // Simpler form for int types that can be safely casted.
    551 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
    552                                              value_type_id) \
    553     static inline void SetTraceValue( \
    554         actual_type arg, \
    555         unsigned char* type, \
    556         unsigned long long* value) { \
    557       *type = value_type_id; \
    558       *value = static_cast<unsigned long long>(arg); \
    559     }
    560 
    561 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
    562 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT)
    563 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
    564 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
    565 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
    566 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
    567 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT)
    568 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
    569 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
    570 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
    571 INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, as_bool, TRACE_VALUE_TYPE_BOOL)
    572 INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, as_double,
    573                                  TRACE_VALUE_TYPE_DOUBLE)
    574 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg, as_pointer,
    575                                  TRACE_VALUE_TYPE_POINTER)
    576 INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg, as_string,
    577                                  TRACE_VALUE_TYPE_STRING)
    578 INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, arg.str(),
    579                                  as_string, TRACE_VALUE_TYPE_COPY_STRING)
    580 
    581 #undef INTERNAL_DECLARE_SET_TRACE_VALUE
    582 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
    583 
    584 // std::string version of SetTraceValue so that trace arguments can be strings.
    585 static inline void SetTraceValue(const std::string& arg,
    586                                  unsigned char* type,
    587                                  unsigned long long* value) {
    588   TraceValueUnion type_value;
    589   type_value.as_string = arg.c_str();
    590   *type = TRACE_VALUE_TYPE_COPY_STRING;
    591   *value = type_value.as_uint;
    592 }
    593 
    594 // base::Time, base::TimeTicks, etc. versions of SetTraceValue to make it easier
    595 // to trace these types.
    596 static inline void SetTraceValue(const base::Time arg,
    597                                  unsigned char* type,
    598                                  unsigned long long* value) {
    599   *type = TRACE_VALUE_TYPE_INT;
    600   *value = arg.ToInternalValue();
    601 }
    602 
    603 static inline void SetTraceValue(const base::TimeTicks arg,
    604                                  unsigned char* type,
    605                                  unsigned long long* value) {
    606   *type = TRACE_VALUE_TYPE_INT;
    607   *value = arg.ToInternalValue();
    608 }
    609 
    610 static inline void SetTraceValue(const base::ThreadTicks arg,
    611                                  unsigned char* type,
    612                                  unsigned long long* value) {
    613   *type = TRACE_VALUE_TYPE_INT;
    614   *value = arg.ToInternalValue();
    615 }
    616 
    617 // These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
    618 // functions are defined here instead of in the macro, because the arg_values
    619 // could be temporary objects, such as std::string. In order to store
    620 // pointers to the internal c_str and pass through to the tracing API,
    621 // the arg_values must live throughout these procedures.
    622 
    623 template <class ARG1_CONVERTABLE_TYPE>
    624 static inline base::trace_event::TraceEventHandle
    625 AddTraceEventWithThreadIdAndTimestamp(
    626     char phase,
    627     const unsigned char* category_group_enabled,
    628     const char* name,
    629     const char* scope,
    630     unsigned long long id,
    631     int thread_id,
    632     const base::TimeTicks& timestamp,
    633     unsigned int flags,
    634     unsigned long long bind_id,
    635     const char* arg1_name,
    636     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) {
    637   const int num_args = 1;
    638   unsigned char arg_types[1] = { TRACE_VALUE_TYPE_CONVERTABLE };
    639   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
    640       convertable_values[1] = {std::move(arg1_val)};
    641   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    642       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    643       timestamp, num_args, &arg1_name, arg_types, NULL, convertable_values,
    644       flags);
    645 }
    646 
    647 template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE>
    648 static inline base::trace_event::TraceEventHandle
    649 AddTraceEventWithThreadIdAndTimestamp(
    650     char phase,
    651     const unsigned char* category_group_enabled,
    652     const char* name,
    653     const char* scope,
    654     unsigned long long id,
    655     int thread_id,
    656     const base::TimeTicks& timestamp,
    657     unsigned int flags,
    658     unsigned long long bind_id,
    659     const char* arg1_name,
    660     const ARG1_TYPE& arg1_val,
    661     const char* arg2_name,
    662     std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
    663   const int num_args = 2;
    664   const char* arg_names[2] = { arg1_name, arg2_name };
    665 
    666   unsigned char arg_types[2];
    667   unsigned long long arg_values[2];
    668   SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
    669   arg_types[1] = TRACE_VALUE_TYPE_CONVERTABLE;
    670   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
    671       convertable_values[2] = {nullptr, std::move(arg2_val)};
    672   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    673       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    674       timestamp, num_args, arg_names, arg_types, arg_values, convertable_values,
    675       flags);
    676 }
    677 
    678 template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE>
    679 static inline base::trace_event::TraceEventHandle
    680 AddTraceEventWithThreadIdAndTimestamp(
    681     char phase,
    682     const unsigned char* category_group_enabled,
    683     const char* name,
    684     const char* scope,
    685     unsigned long long id,
    686     int thread_id,
    687     const base::TimeTicks& timestamp,
    688     unsigned int flags,
    689     unsigned long long bind_id,
    690     const char* arg1_name,
    691     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
    692     const char* arg2_name,
    693     const ARG2_TYPE& arg2_val) {
    694   const int num_args = 2;
    695   const char* arg_names[2] = { arg1_name, arg2_name };
    696 
    697   unsigned char arg_types[2];
    698   unsigned long long arg_values[2];
    699   arg_types[0] = TRACE_VALUE_TYPE_CONVERTABLE;
    700   arg_values[0] = 0;
    701   SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
    702   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
    703       convertable_values[2] = {std::move(arg1_val), nullptr};
    704   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    705       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    706       timestamp, num_args, arg_names, arg_types, arg_values, convertable_values,
    707       flags);
    708 }
    709 
    710 template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE>
    711 static inline base::trace_event::TraceEventHandle
    712 AddTraceEventWithThreadIdAndTimestamp(
    713     char phase,
    714     const unsigned char* category_group_enabled,
    715     const char* name,
    716     const char* scope,
    717     unsigned long long id,
    718     int thread_id,
    719     const base::TimeTicks& timestamp,
    720     unsigned int flags,
    721     unsigned long long bind_id,
    722     const char* arg1_name,
    723     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
    724     const char* arg2_name,
    725     std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
    726   const int num_args = 2;
    727   const char* arg_names[2] = { arg1_name, arg2_name };
    728   unsigned char arg_types[2] =
    729       { TRACE_VALUE_TYPE_CONVERTABLE, TRACE_VALUE_TYPE_CONVERTABLE };
    730   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
    731       convertable_values[2] = {std::move(arg1_val), std::move(arg2_val)};
    732   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    733       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    734       timestamp, num_args, arg_names, arg_types, NULL, convertable_values,
    735       flags);
    736 }
    737 
    738 static inline base::trace_event::TraceEventHandle
    739 AddTraceEventWithThreadIdAndTimestamp(
    740     char phase,
    741     const unsigned char* category_group_enabled,
    742     const char* name,
    743     const char* scope,
    744     unsigned long long id,
    745     int thread_id,
    746     const base::TimeTicks& timestamp,
    747     unsigned int flags,
    748     unsigned long long bind_id) {
    749   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    750       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    751       timestamp, kZeroNumArgs, NULL, NULL, NULL, NULL, flags);
    752 }
    753 
    754 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    755     char phase,
    756     const unsigned char* category_group_enabled,
    757     const char* name,
    758     const char* scope,
    759     unsigned long long id,
    760     unsigned int flags,
    761     unsigned long long bind_id) {
    762   const int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    763   const base::TimeTicks now = base::TimeTicks::Now();
    764   return AddTraceEventWithThreadIdAndTimestamp(
    765       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    766       bind_id);
    767 }
    768 
    769 template<class ARG1_TYPE>
    770 static inline base::trace_event::TraceEventHandle
    771 AddTraceEventWithThreadIdAndTimestamp(
    772     char phase,
    773     const unsigned char* category_group_enabled,
    774     const char* name,
    775     const char* scope,
    776     unsigned long long id,
    777     int thread_id,
    778     const base::TimeTicks& timestamp,
    779     unsigned int flags,
    780     unsigned long long bind_id,
    781     const char* arg1_name,
    782     const ARG1_TYPE& arg1_val) {
    783   const int num_args = 1;
    784   unsigned char arg_types[1];
    785   unsigned long long arg_values[1];
    786   SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
    787   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    788       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    789       timestamp, num_args, &arg1_name, arg_types, arg_values, NULL, flags);
    790 }
    791 
    792 template<class ARG1_TYPE>
    793 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    794     char phase,
    795     const unsigned char* category_group_enabled,
    796     const char* name,
    797     const char* scope,
    798     unsigned long long id,
    799     unsigned int flags,
    800     unsigned long long bind_id,
    801     const char* arg1_name,
    802     const ARG1_TYPE& arg1_val) {
    803   int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    804   base::TimeTicks now = base::TimeTicks::Now();
    805   return AddTraceEventWithThreadIdAndTimestamp(
    806       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    807       bind_id, arg1_name, arg1_val);
    808 }
    809 
    810 template <class ARG1_CONVERTABLE_TYPE>
    811 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    812     char phase,
    813     const unsigned char* category_group_enabled,
    814     const char* name,
    815     const char* scope,
    816     unsigned long long id,
    817     unsigned int flags,
    818     unsigned long long bind_id,
    819     const char* arg1_name,
    820     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) {
    821   int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    822   base::TimeTicks now = base::TimeTicks::Now();
    823   return AddTraceEventWithThreadIdAndTimestamp(
    824       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    825       bind_id, arg1_name, std::move(arg1_val));
    826 }
    827 
    828 template<class ARG1_TYPE, class ARG2_TYPE>
    829 static inline base::trace_event::TraceEventHandle
    830 AddTraceEventWithThreadIdAndTimestamp(
    831     char phase,
    832     const unsigned char* category_group_enabled,
    833     const char* name,
    834     const char* scope,
    835     unsigned long long id,
    836     int thread_id,
    837     const base::TimeTicks& timestamp,
    838     unsigned int flags,
    839     unsigned long long bind_id,
    840     const char* arg1_name,
    841     const ARG1_TYPE& arg1_val,
    842     const char* arg2_name,
    843     const ARG2_TYPE& arg2_val) {
    844   const int num_args = 2;
    845   const char* arg_names[2] = { arg1_name, arg2_name };
    846   unsigned char arg_types[2];
    847   unsigned long long arg_values[2];
    848   SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
    849   SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
    850   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
    851       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
    852       timestamp, num_args, arg_names, arg_types, arg_values, NULL, flags);
    853 }
    854 
    855 template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE>
    856 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    857     char phase,
    858     const unsigned char* category_group_enabled,
    859     const char* name,
    860     const char* scope,
    861     unsigned long long id,
    862     unsigned int flags,
    863     unsigned long long bind_id,
    864     const char* arg1_name,
    865     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
    866     const char* arg2_name,
    867     const ARG2_TYPE& arg2_val) {
    868   int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    869   base::TimeTicks now = base::TimeTicks::Now();
    870   return AddTraceEventWithThreadIdAndTimestamp(
    871       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    872       bind_id, arg1_name, std::move(arg1_val), arg2_name, arg2_val);
    873 }
    874 
    875 template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE>
    876 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    877     char phase,
    878     const unsigned char* category_group_enabled,
    879     const char* name,
    880     const char* scope,
    881     unsigned long long id,
    882     unsigned int flags,
    883     unsigned long long bind_id,
    884     const char* arg1_name,
    885     const ARG1_TYPE& arg1_val,
    886     const char* arg2_name,
    887     std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
    888   int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    889   base::TimeTicks now = base::TimeTicks::Now();
    890   return AddTraceEventWithThreadIdAndTimestamp(
    891       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    892       bind_id, arg1_name, arg1_val, arg2_name, std::move(arg2_val));
    893 }
    894 
    895 template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE>
    896 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    897     char phase,
    898     const unsigned char* category_group_enabled,
    899     const char* name,
    900     const char* scope,
    901     unsigned long long id,
    902     unsigned int flags,
    903     unsigned long long bind_id,
    904     const char* arg1_name,
    905     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
    906     const char* arg2_name,
    907     std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
    908   int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    909   base::TimeTicks now = base::TimeTicks::Now();
    910   return AddTraceEventWithThreadIdAndTimestamp(
    911       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    912       bind_id, arg1_name, std::move(arg1_val), arg2_name, std::move(arg2_val));
    913 }
    914 
    915 template<class ARG1_TYPE, class ARG2_TYPE>
    916 static inline base::trace_event::TraceEventHandle AddTraceEvent(
    917     char phase,
    918     const unsigned char* category_group_enabled,
    919     const char* name,
    920     const char* scope,
    921     unsigned long long id,
    922     unsigned int flags,
    923     unsigned long long bind_id,
    924     const char* arg1_name,
    925     const ARG1_TYPE& arg1_val,
    926     const char* arg2_name,
    927     const ARG2_TYPE& arg2_val) {
    928   int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
    929   base::TimeTicks now = base::TimeTicks::Now();
    930   return AddTraceEventWithThreadIdAndTimestamp(
    931       phase, category_group_enabled, name, scope, id, thread_id, now, flags,
    932       bind_id, arg1_name, arg1_val, arg2_name, arg2_val);
    933 }
    934 
    935 template <class ARG1_CONVERTABLE_TYPE>
    936 static inline void AddMetadataEvent(
    937     const unsigned char* category_group_enabled,
    938     const char* event_name,
    939     const char* arg_name,
    940     std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg_value) {
    941   const char* arg_names[1] = {arg_name};
    942   unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE};
    943   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
    944       convertable_values[1] = {std::move(arg_value)};
    945   base::trace_event::TraceLog::GetInstance()->AddMetadataEvent(
    946       category_group_enabled, event_name,
    947       1,  // num_args
    948       arg_names, arg_types,
    949       nullptr,  // arg_values
    950       convertable_values, TRACE_EVENT_FLAG_NONE);
    951 }
    952 
    953 template <class ARG1_TYPE>
    954 static void AddMetadataEvent(const unsigned char* category_group_enabled,
    955                              const char* event_name,
    956                              const char* arg_name,
    957                              const ARG1_TYPE& arg_val) {
    958   const int num_args = 1;
    959   const char* arg_names[1] = {arg_name};
    960   unsigned char arg_types[1];
    961   unsigned long long arg_values[1];
    962   SetTraceValue(arg_val, &arg_types[0], &arg_values[0]);
    963 
    964   base::trace_event::TraceLog::GetInstance()->AddMetadataEvent(
    965       category_group_enabled, event_name, num_args, arg_names, arg_types,
    966       arg_values, nullptr, TRACE_EVENT_FLAG_NONE);
    967 }
    968 
    969 // Used by TRACE_EVENTx macros. Do not use directly.
    970 class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer {
    971  public:
    972   // Note: members of data_ intentionally left uninitialized. See Initialize.
    973   ScopedTracer() : p_data_(NULL) {}
    974 
    975   ~ScopedTracer() {
    976     if (p_data_ && *data_.category_group_enabled)
    977       TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
    978           data_.category_group_enabled, data_.name, data_.event_handle);
    979   }
    980 
    981   void Initialize(const unsigned char* category_group_enabled,
    982                   const char* name,
    983                   base::trace_event::TraceEventHandle event_handle) {
    984     data_.category_group_enabled = category_group_enabled;
    985     data_.name = name;
    986     data_.event_handle = event_handle;
    987     p_data_ = &data_;
    988   }
    989 
    990  private:
    991   // This Data struct workaround is to avoid initializing all the members
    992   // in Data during construction of this object, since this object is always
    993   // constructed, even when tracing is disabled. If the members of Data were
    994   // members of this class instead, compiler warnings occur about potential
    995   // uninitialized accesses.
    996   struct Data {
    997     const unsigned char* category_group_enabled;
    998     const char* name;
    999     base::trace_event::TraceEventHandle event_handle;
   1000   };
   1001   Data* p_data_;
   1002   Data data_;
   1003 };
   1004 
   1005 // Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
   1006 class TRACE_EVENT_API_CLASS_EXPORT ScopedTraceBinaryEfficient {
   1007  public:
   1008   ScopedTraceBinaryEfficient(const char* category_group, const char* name);
   1009   ~ScopedTraceBinaryEfficient();
   1010 
   1011  private:
   1012   const unsigned char* category_group_enabled_;
   1013   const char* name_;
   1014   base::trace_event::TraceEventHandle event_handle_;
   1015 };
   1016 
   1017 // This macro generates less code then TRACE_EVENT0 but is also
   1018 // slower to execute when tracing is off. It should generally only be
   1019 // used with code that is seldom executed or conditionally executed
   1020 // when debugging.
   1021 // For now the category_group must be "gpu".
   1022 #define TRACE_EVENT_BINARY_EFFICIENT0(category_group, name) \
   1023     trace_event_internal::ScopedTraceBinaryEfficient \
   1024         INTERNAL_TRACE_EVENT_UID(scoped_trace)(category_group, name);
   1025 
   1026 // TraceEventSamplingStateScope records the current sampling state
   1027 // and sets a new sampling state. When the scope exists, it restores
   1028 // the sampling state having recorded.
   1029 template<size_t BucketNumber>
   1030 class TraceEventSamplingStateScope {
   1031  public:
   1032   TraceEventSamplingStateScope(const char* category_and_name) {
   1033     previous_state_ = TraceEventSamplingStateScope<BucketNumber>::Current();
   1034     TraceEventSamplingStateScope<BucketNumber>::Set(category_and_name);
   1035   }
   1036 
   1037   ~TraceEventSamplingStateScope() {
   1038     TraceEventSamplingStateScope<BucketNumber>::Set(previous_state_);
   1039   }
   1040 
   1041   static inline const char* Current() {
   1042     return reinterpret_cast<const char*>(TRACE_EVENT_API_ATOMIC_LOAD(
   1043       g_trace_state[BucketNumber]));
   1044   }
   1045 
   1046   static inline void Set(const char* category_and_name) {
   1047     TRACE_EVENT_API_ATOMIC_STORE(
   1048       g_trace_state[BucketNumber],
   1049       reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(
   1050         const_cast<char*>(category_and_name)));
   1051   }
   1052 
   1053  private:
   1054   const char* previous_state_;
   1055 };
   1056 
   1057 }  // namespace trace_event_internal
   1058 
   1059 namespace base {
   1060 namespace trace_event {
   1061 
   1062 template<typename IDType> class TraceScopedTrackableObject {
   1063  public:
   1064   TraceScopedTrackableObject(const char* category_group, const char* name,
   1065       IDType id)
   1066     : category_group_(category_group),
   1067       name_(name),
   1068       id_(id) {
   1069     TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group_, name_, id_);
   1070   }
   1071 
   1072   template <typename ArgType> void snapshot(ArgType snapshot) {
   1073     TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group_, name_, id_, snapshot);
   1074   }
   1075 
   1076   ~TraceScopedTrackableObject() {
   1077     TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group_, name_, id_);
   1078   }
   1079 
   1080  private:
   1081   const char* category_group_;
   1082   const char* name_;
   1083   IDType id_;
   1084 
   1085   DISALLOW_COPY_AND_ASSIGN(TraceScopedTrackableObject);
   1086 };
   1087 
   1088 }  // namespace trace_event
   1089 }  // namespace base
   1090 
   1091 #endif  // BASE_TRACE_EVENT_TRACE_EVENT_H_
   1092