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