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