Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / TraceEvent.h
blob508d32791143f39156fea7730494a5ad69567b72
1 /*
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
6 * are met:
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.
30 #ifndef TraceEvent_h
31 #define TraceEvent_h
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");
69 // ...;
70 // }
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(
105 // const char* name,
106 // unsigned long long id,
107 // double timestamp,
108 // int num_args,
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, ...) \
150 do { \
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__); \
157 } while (0)
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
161 // ends.
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, ...) \
179 do { \
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__); \
189 } while (0)
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, ...) \
195 do { \
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__); \
205 } while (0)
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, ...) \
210 do { \
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__); \
217 } while (0)
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)
229 namespace blink {
231 namespace TraceEvent {
233 // Specify these values when the corresponding argument of addTraceEvent is not
234 // used.
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.
241 class TraceID {
242 public:
243 template<bool dummyMangle> class MangleBehavior {
244 public:
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; }
247 private:
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; }
281 private:
282 unsigned long long m_data;
285 // Simple union to store various types as unsigned long long.
286 union TraceValueUnion {
287 bool m_bool;
288 unsigned long long m_uint;
289 long long m_int;
290 double m_double;
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 {
297 public:
298 explicit TraceStringWithCopy(const char* str) : m_str(str) { }
299 const char* str() const { return m_str; }
300 private:
301 const char* 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&)
363 return nullptr;
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(
391 char phase,
392 const unsigned char* categoryEnabled,
393 const char* name,
394 unsigned long long id,
395 double timestamp,
396 unsigned char flags)
398 return TRACE_EVENT_API_ADD_TRACE_EVENT(
399 phase, categoryEnabled, name, id, timestamp,
400 zeroNumArgs, 0, 0, 0,
401 flags);
404 template<typename ARG1_TYPE>
405 static inline TraceEventHandle addTraceEvent(
406 char phase,
407 const unsigned char* categoryEnabled,
408 const char* name,
409 unsigned long long id,
410 double timestamp,
411 unsigned char flags,
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),
424 nullptr,
425 flags);
427 return TRACE_EVENT_API_ADD_TRACE_EVENT(
428 phase, categoryEnabled, name, id, timestamp,
429 numArgs, &arg1Name, argTypes, argValues,
430 flags);
433 template<typename ARG1_TYPE, typename ARG2_TYPE>
434 static inline TraceEventHandle addTraceEvent(
435 char phase,
436 const unsigned char* categoryEnabled,
437 const char* name,
438 unsigned long long id,
439 double timestamp,
440 unsigned char flags,
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),
458 flags);
460 return TRACE_EVENT_API_ADD_TRACE_EVENT(
461 phase, categoryEnabled, name, id, timestamp,
462 numArgs, argNames, argTypes, argValues,
463 flags);
466 static inline TraceEventHandle addTraceEvent(
467 char phase,
468 const unsigned char* categoryEnabled,
469 const char* name,
470 unsigned long long id,
471 unsigned char flags)
473 return addTraceEvent(phase, categoryEnabled, name, id, systemTraceTime(), flags);
476 template<typename ARG1_TYPE>
477 static inline TraceEventHandle addTraceEvent(
478 char phase,
479 const unsigned char* categoryEnabled,
480 const char* name,
481 unsigned long long id,
482 unsigned char flags,
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(
492 char phase,
493 const unsigned char* categoryEnabled,
494 const char* name,
495 unsigned long long id,
496 unsigned char flags,
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.
506 class ScopedTracer {
507 public:
508 // Note: members of m_data intentionally left uninitialized. See initialize.
509 ScopedTracer() : m_pdata(0) { }
510 ~ScopedTracer()
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;
519 m_data.name = name;
520 m_data.eventHandle = eventHandle;
521 m_pdata = &m_data;
524 private:
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.
530 struct Data {
531 const unsigned char* categoryGroupEnabled;
532 const char* name;
533 TraceEventHandle eventHandle;
535 Data* m_pdata;
536 Data m_data;
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);
545 public:
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);
567 private:
568 const char* m_previousState;
571 template<typename IDType> class TraceScopedTrackableObject {
572 WTF_MAKE_NONCOPYABLE(TraceScopedTrackableObject);
573 public:
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);
585 private:
586 const char* m_categoryGroup;
587 const char* m_name;
588 IDType m_id;
591 } // namespace TraceEvent
593 } // namespace blink
595 #endif