2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // This header file defines implementation details of how the trace macros in
27 // TraceEventCommon.h collect and store trace events. Anything not
28 // implementation-specific should go in TraceEventCommon.h instead of here.
33 #include "platform/EventTracer.h"
34 #include "platform/TraceEventCommon.h"
36 #include "wtf/CurrentTime.h"
37 #include "wtf/DynamicAnnotations.h"
38 #include "wtf/PassRefPtr.h"
39 #include "wtf/text/CString.h"
41 ////////////////////////////////////////////////////////////////////////////////
42 // Implementation specific tracing API definitions.
44 // By default, const char* argument values are assumed to have long-lived scope
45 // and will not be copied. Use this macro to force a const char* to be copied.
46 #define TRACE_STR_COPY(str) \
47 blink::TraceEvent::TraceStringWithCopy(str)
49 // By default, uint64 ID argument values are not mangled with the Process ID in
50 // TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
51 #define TRACE_ID_MANGLE(id) \
52 blink::TraceEvent::TraceID::ForceMangle(id)
54 // By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
55 // macros. Use this macro to prevent Process ID mangling.
56 #define TRACE_ID_DONT_MANGLE(id) \
57 blink::TraceEvent::TraceID::DontMangle(id)
60 // Creates a scope of a sampling state with the given category and name (both must
61 // be constant strings). These states are intended for a sampling profiler.
62 // Implementation note: we store category and name together because we don't
63 // want the inconsistency/expense of storing two pointers.
64 // |thread_bucket| is [0..2] and is used to statically isolate samples in one
65 // thread from others.
67 // { // The sampling state is set within this scope.
68 // TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
71 #define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
72 TraceEvent::SamplingStateScope<bucket_number> traceEventSamplingScope(category "\0" name);
74 // Returns a current sampling state of the given bucket.
75 // The format of the returned string is "category\0name".
76 #define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
77 TraceEvent::SamplingStateScope<bucket_number>::current()
79 // Sets a current sampling state of the given bucket.
80 // |category| and |name| have to be constant strings.
81 #define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
82 TraceEvent::SamplingStateScope<bucket_number>::set(category "\0" name)
84 // Sets a current sampling state of the given bucket.
85 // |categoryAndName| doesn't need to be a constant string.
86 // The format of the string is "category\0name".
87 #define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, categoryAndName) \
88 TraceEvent::SamplingStateScope<bucket_number>::set(categoryAndName)
90 // Get a pointer to the enabled state of the given trace category. Only
91 // long-lived literal strings should be given as the category name. The returned
92 // pointer can be held permanently in a local static for example. If the
93 // unsigned char is non-zero, tracing is enabled. If tracing is enabled,
94 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
95 // between the load of the tracing state and the call to
96 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
97 // for best performance when tracing is disabled.
98 // const unsigned char*
99 // TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
100 #define TRACE_EVENT_API_GET_CATEGORY_ENABLED \
101 blink::EventTracer::getTraceCategoryEnabledFlag
103 // Add a trace event to the platform tracing system.
104 // blink::TraceEvent::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT(
106 // unsigned long long id,
109 // const char** arg_names,
110 // const unsigned char* arg_types,
111 // const unsigned long long* arg_values,
112 // PassRefPtr<ConvertableToTraceFormat> convertableValues[],
113 // unsigned char flags)
114 #define TRACE_EVENT_API_ADD_TRACE_EVENT \
115 blink::EventTracer::addTraceEvent
117 // Set the duration field of a COMPLETE trace event.
118 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
119 // blink::TraceEvent::TraceEventHandle handle)
120 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
121 blink::EventTracer::updateTraceEventDuration
123 ////////////////////////////////////////////////////////////////////////////////
125 // Implementation detail: trace event macros create temporary variables
126 // to keep instrumentation overhead low. These macros give each temporary
127 // variable a unique name based on the line number to prevent name collissions.
128 #define INTERNAL_TRACE_EVENT_UID3(a, b) \
129 trace_event_unique_##a##b
130 #define INTERNAL_TRACE_EVENT_UID2(a, b) \
131 INTERNAL_TRACE_EVENT_UID3(a, b)
132 #define INTERNALTRACEEVENTUID(name_prefix) \
133 INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
135 // Implementation detail: internal macro to create static category.
136 // - WTF_ANNOTATE_BENIGN_RACE, see Thread Safety above.
138 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \
139 static const unsigned char* INTERNALTRACEEVENTUID(categoryGroupEnabled) = 0; \
140 WTF_ANNOTATE_BENIGN_RACE(&INTERNALTRACEEVENTUID(categoryGroupEnabled), \
141 "trace_event category"); \
142 if (!INTERNALTRACEEVENTUID(categoryGroupEnabled)) { \
143 INTERNALTRACEEVENTUID(categoryGroupEnabled) = \
144 TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); \
147 // Implementation detail: internal macro to create static category and add
148 // event if the category is enabled.
149 #define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
151 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
152 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
153 blink::TraceEvent::addTraceEvent( \
154 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
155 blink::TraceEvent::noEventId, flags, ##__VA_ARGS__); \
159 // Implementation detail: internal macro to create static category and add begin
160 // event if the category is enabled. Also adds the end event when the scope
162 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
163 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
164 blink::TraceEvent::ScopedTracer INTERNALTRACEEVENTUID(scopedTracer); \
165 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
166 blink::TraceEvent::TraceEventHandle h = \
167 blink::TraceEvent::addTraceEvent( \
168 TRACE_EVENT_PHASE_COMPLETE, \
169 INTERNALTRACEEVENTUID(categoryGroupEnabled), \
170 name, blink::TraceEvent::noEventId, \
171 TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
172 INTERNALTRACEEVENTUID(scopedTracer).initialize( \
173 INTERNALTRACEEVENTUID(categoryGroupEnabled), name, h); \
176 // Implementation detail: internal macro to create static category and add
177 // event if the category is enabled.
178 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, ...) \
180 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
181 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
182 unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
183 blink::TraceEvent::TraceID traceEventTraceID( \
184 id, &traceEventFlags); \
185 blink::TraceEvent::addTraceEvent( \
186 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), \
187 name, traceEventTraceID.data(), traceEventFlags, ##__VA_ARGS__); \
192 // Implementation detail: internal macro to create static category and add event
193 // if the category is enabled.
194 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP(phase, category, name, id, timestamp, flags, ...) \
196 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
197 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
198 unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
199 blink::TraceEvent::TraceID traceEventTraceID( \
200 id, &traceEventFlags); \
201 blink::TraceEvent::addTraceEvent( \
202 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), \
203 name, traceEventTraceID.data(), timestamp, traceEventFlags, ##__VA_ARGS__); \
207 // Implementation detail: internal macro to create static category and add
208 // event if the category is enabled.
209 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name, timestamp, flags, ...) \
211 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
212 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
213 blink::TraceEvent::addTraceEvent( \
214 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
215 blink::TraceEvent::noEventId, timestamp, flags, ##__VA_ARGS__); \
220 // These values must be in sync with base::debug::TraceLog::CategoryGroupEnabledFlags.
221 #define ENABLED_FOR_RECORDING (1 << 0)
222 #define ENABLED_FOR_EVENT_CALLBACK (1 << 2)
224 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
225 (*INTERNALTRACEEVENTUID(categoryGroupEnabled) & (ENABLED_FOR_RECORDING | ENABLED_FOR_EVENT_CALLBACK))
227 #define INTERNAL_TRACE_MEMORY(category, name)
231 namespace TraceEvent
{
233 // Specify these values when the corresponding argument of addTraceEvent is not
235 const int zeroNumArgs
= 0;
236 const unsigned long long noEventId
= 0;
238 // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
239 // are mangled with the Process ID so that they are unlikely to collide when the
240 // same pointer is used on different processes.
243 template<bool dummyMangle
> class MangleBehavior
{
245 template<typename T
> explicit MangleBehavior(T id
) : m_data(reinterpret_cast<unsigned long long>(id
)) { }
246 unsigned long long data() const { return m_data
; }
248 unsigned long long m_data
;
250 typedef MangleBehavior
<false> DontMangle
;
251 typedef MangleBehavior
<true> ForceMangle
;
253 TraceID(const void* id
, unsigned char* flags
) :
254 m_data(static_cast<unsigned long long>(reinterpret_cast<unsigned long>(id
)))
256 *flags
|= TRACE_EVENT_FLAG_MANGLE_ID
;
258 TraceID(ForceMangle id
, unsigned char* flags
) : m_data(id
.data())
260 *flags
|= TRACE_EVENT_FLAG_MANGLE_ID
;
262 TraceID(DontMangle id
, unsigned char*) : m_data(id
.data()) { }
263 TraceID(unsigned long long id
, unsigned char*) : m_data(id
) { }
264 TraceID(unsigned long id
, unsigned char*) : m_data(id
) { }
265 TraceID(unsigned id
, unsigned char*) : m_data(id
) { }
266 TraceID(unsigned short id
, unsigned char*) : m_data(id
) { }
267 TraceID(unsigned char id
, unsigned char*) : m_data(id
) { }
268 TraceID(long long id
, unsigned char*) :
269 m_data(static_cast<unsigned long long>(id
)) { }
270 TraceID(long id
, unsigned char*) :
271 m_data(static_cast<unsigned long long>(id
)) { }
272 TraceID(int id
, unsigned char*) :
273 m_data(static_cast<unsigned long long>(id
)) { }
274 TraceID(short id
, unsigned char*) :
275 m_data(static_cast<unsigned long long>(id
)) { }
276 TraceID(signed char id
, unsigned char*) :
277 m_data(static_cast<unsigned long long>(id
)) { }
279 unsigned long long data() const { return m_data
; }
282 unsigned long long m_data
;
285 // Simple union to store various types as unsigned long long.
286 union TraceValueUnion
{
288 unsigned long long m_uint
;
291 const void* m_pointer
;
292 const char* m_string
;
295 // Simple container for const char* that should be copied instead of retained.
296 class TraceStringWithCopy
{
298 explicit TraceStringWithCopy(const char* str
) : m_str(str
) { }
299 const char* str() const { return m_str
; }
304 // Define setTraceValue for each allowed type. It stores the type and
305 // value in the return arguments. This allows this API to avoid declaring any
306 // structures so that it is portable to third_party libraries.
307 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actualType, argExpression, unionMember, valueTypeId) \
308 static inline void setTraceValue(actualType arg, unsigned char* type, unsigned long long* value) { \
309 TraceValueUnion typeValue; \
310 typeValue.unionMember = argExpression; \
311 *type = valueTypeId; \
312 *value = typeValue.m_uint; \
314 // Simpler form for int types that can be safely casted.
315 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actualType, valueTypeId) \
316 static inline void setTraceValue(actualType arg, \
317 unsigned char* type, \
318 unsigned long long* value) { \
319 *type = valueTypeId; \
320 *value = static_cast<unsigned long long>(arg); \
323 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT
)
324 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned, TRACE_VALUE_TYPE_UINT
)
325 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT
)
326 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT
)
327 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT
)
328 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT
)
329 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT
)
330 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT
)
331 INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg
, m_bool
, TRACE_VALUE_TYPE_BOOL
)
332 INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg
, m_double
, TRACE_VALUE_TYPE_DOUBLE
)
333 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg
, m_pointer
, TRACE_VALUE_TYPE_POINTER
)
334 INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg
, m_string
, TRACE_VALUE_TYPE_STRING
)
335 INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy
&, arg
.str(), m_string
, TRACE_VALUE_TYPE_COPY_STRING
)
337 #undef INTERNAL_DECLARE_SET_TRACE_VALUE
338 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
340 // WTF::String version of setTraceValue so that trace arguments can be strings.
341 static inline void setTraceValue(const WTF::CString
& arg
, unsigned char* type
, unsigned long long* value
)
343 TraceValueUnion typeValue
;
344 typeValue
.m_string
= arg
.data();
345 *type
= TRACE_VALUE_TYPE_COPY_STRING
;
346 *value
= typeValue
.m_uint
;
349 static inline void setTraceValue(ConvertableToTraceFormat
*, unsigned char* type
, unsigned long long*)
351 *type
= TRACE_VALUE_TYPE_CONVERTABLE
;
354 template<typename T
> static inline void setTraceValue(const PassRefPtr
<T
>& ptr
, unsigned char* type
, unsigned long long* value
)
356 setTraceValue(ptr
.get(), type
, value
);
359 template<typename T
> struct ConvertableToTraceFormatTraits
{
360 static const bool isConvertable
= false;
361 static PassRefPtr
<ConvertableToTraceFormat
> moveFromIfConvertable(const T
&)
367 template<typename T
> struct ConvertableToTraceFormatTraits
<PassRefPtr
<T
>> {
368 static const bool isConvertable
= WTF::IsSubclass
<T
, TraceEvent::ConvertableToTraceFormat
>::value
;
369 static PassRefPtr
<ConvertableToTraceFormat
> moveFromIfConvertable(const PassRefPtr
<T
>& convertableToTraceFormat
)
371 return convertableToTraceFormat
;
375 template<typename T
> bool isConvertableToTraceFormat(const T
&)
377 return ConvertableToTraceFormatTraits
<T
>::isConvertable
;
380 template<typename T
> PassRefPtr
<ConvertableToTraceFormat
> moveFromIfConvertableToTraceFormat(const T
& value
)
382 return ConvertableToTraceFormatTraits
<T
>::moveFromIfConvertable(value
);
385 // These addTraceEvent template functions are defined here instead of in the
386 // macro, because the arg values could be temporary string objects. In order to
387 // store pointers to the internal c_str and pass through to the tracing API, the
388 // arg values must live throughout these procedures.
390 static inline TraceEventHandle
addTraceEvent(
392 const unsigned char* categoryEnabled
,
394 unsigned long long id
,
398 return TRACE_EVENT_API_ADD_TRACE_EVENT(
399 phase
, categoryEnabled
, name
, id
, timestamp
,
400 zeroNumArgs
, 0, 0, 0,
404 template<typename ARG1_TYPE
>
405 static inline TraceEventHandle
addTraceEvent(
407 const unsigned char* categoryEnabled
,
409 unsigned long long id
,
412 const char* arg1Name
,
413 const ARG1_TYPE
& arg1Val
)
415 const int numArgs
= 1;
416 unsigned char argTypes
[1];
417 unsigned long long argValues
[1];
418 setTraceValue(arg1Val
, &argTypes
[0], &argValues
[0]);
419 if (isConvertableToTraceFormat(arg1Val
)) {
420 return TRACE_EVENT_API_ADD_TRACE_EVENT(
421 phase
, categoryEnabled
, name
, id
, timestamp
,
422 numArgs
, &arg1Name
, argTypes
, argValues
,
423 moveFromIfConvertableToTraceFormat(arg1Val
),
427 return TRACE_EVENT_API_ADD_TRACE_EVENT(
428 phase
, categoryEnabled
, name
, id
, timestamp
,
429 numArgs
, &arg1Name
, argTypes
, argValues
,
433 template<typename ARG1_TYPE
, typename ARG2_TYPE
>
434 static inline TraceEventHandle
addTraceEvent(
436 const unsigned char* categoryEnabled
,
438 unsigned long long id
,
441 const char* arg1Name
,
442 const ARG1_TYPE
& arg1Val
,
443 const char* arg2Name
,
444 const ARG2_TYPE
& arg2Val
)
446 const int numArgs
= 2;
447 const char* argNames
[2] = { arg1Name
, arg2Name
};
448 unsigned char argTypes
[2];
449 unsigned long long argValues
[2];
450 setTraceValue(arg1Val
, &argTypes
[0], &argValues
[0]);
451 setTraceValue(arg2Val
, &argTypes
[1], &argValues
[1]);
452 if (isConvertableToTraceFormat(arg1Val
) || isConvertableToTraceFormat(arg2Val
)) {
453 return TRACE_EVENT_API_ADD_TRACE_EVENT(
454 phase
, categoryEnabled
, name
, id
, timestamp
,
455 numArgs
, argNames
, argTypes
, argValues
,
456 moveFromIfConvertableToTraceFormat(arg1Val
),
457 moveFromIfConvertableToTraceFormat(arg2Val
),
460 return TRACE_EVENT_API_ADD_TRACE_EVENT(
461 phase
, categoryEnabled
, name
, id
, timestamp
,
462 numArgs
, argNames
, argTypes
, argValues
,
466 static inline TraceEventHandle
addTraceEvent(
468 const unsigned char* categoryEnabled
,
470 unsigned long long id
,
473 return addTraceEvent(phase
, categoryEnabled
, name
, id
, systemTraceTime(), flags
);
476 template<typename ARG1_TYPE
>
477 static inline TraceEventHandle
addTraceEvent(
479 const unsigned char* categoryEnabled
,
481 unsigned long long id
,
483 const char* arg1Name
,
484 const ARG1_TYPE
& arg1Val
)
486 return addTraceEvent(phase
, categoryEnabled
, name
, id
, systemTraceTime(), flags
, arg1Name
, arg1Val
);
490 template<typename ARG1_TYPE
, typename ARG2_TYPE
>
491 static inline TraceEventHandle
addTraceEvent(
493 const unsigned char* categoryEnabled
,
495 unsigned long long id
,
497 const char* arg1Name
,
498 const ARG1_TYPE
& arg1Val
,
499 const char* arg2Name
,
500 const ARG2_TYPE
& arg2Val
)
502 return addTraceEvent(phase
, categoryEnabled
, name
, id
, systemTraceTime(), flags
, arg1Name
, arg1Val
, arg2Name
, arg2Val
);
505 // Used by TRACE_EVENTx macro. Do not use directly.
508 // Note: members of m_data intentionally left uninitialized. See initialize.
509 ScopedTracer() : m_pdata(0) { }
512 if (m_pdata
&& *m_pdata
->categoryGroupEnabled
)
513 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(m_data
.categoryGroupEnabled
, m_data
.name
, m_data
.eventHandle
);
516 void initialize(const unsigned char* categoryGroupEnabled
, const char* name
, TraceEventHandle eventHandle
)
518 m_data
.categoryGroupEnabled
= categoryGroupEnabled
;
520 m_data
.eventHandle
= eventHandle
;
525 // This Data struct workaround is to avoid initializing all the members
526 // in Data during construction of this object, since this object is always
527 // constructed, even when tracing is disabled. If the members of Data were
528 // members of this class instead, compiler warnings occur about potential
529 // uninitialized accesses.
531 const unsigned char* categoryGroupEnabled
;
533 TraceEventHandle eventHandle
;
539 // TraceEventSamplingStateScope records the current sampling state
540 // and sets a new sampling state. When the scope exists, it restores
541 // the sampling state having recorded.
542 template<size_t BucketNumber
>
543 class SamplingStateScope
{
544 WTF_MAKE_FAST_ALLOCATED(SamplingStateScope
);
546 SamplingStateScope(const char* categoryAndName
)
548 m_previousState
= SamplingStateScope
<BucketNumber
>::current();
549 SamplingStateScope
<BucketNumber
>::set(categoryAndName
);
552 ~SamplingStateScope()
554 SamplingStateScope
<BucketNumber
>::set(m_previousState
);
557 // FIXME: Make load/store to traceSamplingState[] thread-safe and atomic.
558 static const char* current()
560 return reinterpret_cast<const char*>(*blink::traceSamplingState
[BucketNumber
]);
562 static void set(const char* categoryAndName
)
564 *blink::traceSamplingState
[BucketNumber
] = reinterpret_cast<TraceEventAPIAtomicWord
>(categoryAndName
);
568 const char* m_previousState
;
571 template<typename IDType
> class TraceScopedTrackableObject
{
572 WTF_MAKE_NONCOPYABLE(TraceScopedTrackableObject
);
574 TraceScopedTrackableObject(const char* categoryGroup
, const char* name
, IDType id
)
575 : m_categoryGroup(categoryGroup
), m_name(name
), m_id(id
)
577 TRACE_EVENT_OBJECT_CREATED_WITH_ID(m_categoryGroup
, m_name
, m_id
);
580 ~TraceScopedTrackableObject()
582 TRACE_EVENT_OBJECT_DELETED_WITH_ID(m_categoryGroup
, m_name
, m_id
);
586 const char* m_categoryGroup
;
591 } // namespace TraceEvent