Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: third_party/WebKit/Source/platform/TraceEvent.h

Issue 2341333003: Use chromium trace_event implementation in blink (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be
3 * 3 // found in the LICENSE file.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
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.
13 *
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.
24 */
25
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.
29 4
30 #ifndef TraceEvent_h 5 #ifndef TraceEvent_h
31 #define TraceEvent_h 6 #define TraceEvent_h
32 7
33 #include "platform/EventTracer.h" 8 #include "base/time/time.h"
34 #include "platform/TraceEventCommon.h" 9 #include "base/trace_event/trace_event.h"
10 #include "wtf/text/CString.h"
35 11
36 #include "platform/TracedValue.h" 12 namespace WTF {
37 #include "wtf/Allocator.h"
38 #include "wtf/DynamicAnnotations.h"
39 #include "wtf/Noncopyable.h"
40 #include "wtf/text/CString.h"
41 #include <memory>
42 13
43 //////////////////////////////////////////////////////////////////////////////// 14 // CString version of SetTraceValue so that trace arguments can be strings.
44 // Implementation specific tracing API definitions. 15 static inline void SetTraceValue(const CString& arg, unsigned char* type, unsign ed long long* value)
16 {
17 trace_event_internal::TraceValueUnion typeValue;
18 typeValue.as_string = arg.data();
19 *type = TRACE_VALUE_TYPE_COPY_STRING;
20 *value = typeValue.as_uint;
21 }
45 22
46 // By default, const char* argument values are assumed to have long-lived scope 23 } // namespace WTF
47 // and will not be copied. Use this macro to force a const char* to be copied.
48 #define TRACE_STR_COPY(str) \
49 blink::TraceEvent::TraceStringWithCopy(str)
50
51 // By default, uint64 ID argument values are not mangled with the Process ID in
52 // TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
53 #define TRACE_ID_MANGLE(id) \
54 blink::TraceEvent::TraceID::ForceMangle(id)
55
56 // By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
57 // macros. Use this macro to prevent Process ID mangling.
58 #define TRACE_ID_DONT_MANGLE(id) \
59 blink::TraceEvent::TraceID::DontMangle(id)
60
61 // By default, trace IDs are eventually converted to a single 64-bit number. Use
62 // this macro to add a scope string.
63 #define TRACE_ID_WITH_SCOPE(scope, id) \
64 blink::TraceEvent::TraceID::WithScope(scope, id)
65
66 // Creates a scope of a sampling state with the given category and name (both mu st
67 // be constant strings). These states are intended for a sampling profiler.
68 // Implementation note: we store category and name together because we don't
69 // want the inconsistency/expense of storing two pointers.
70 // |thread_bucket| is [0..2] and is used to statically isolate samples in one
71 // thread from others.
72 //
73 // { // The sampling state is set within this scope.
74 // TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
75 // ...;
76 // }
77 #define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, na me) \
78 TraceEvent::SamplingStateScope<bucket_number> traceEventSamplingScope(catego ry "\0" name);
79
80 // Returns a current sampling state of the given bucket.
81 // The format of the returned string is "category\0name".
82 #define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
83 TraceEvent::SamplingStateScope<bucket_number>::current()
84
85 // Sets a current sampling state of the given bucket.
86 // |category| and |name| have to be constant strings.
87 #define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
88 TraceEvent::SamplingStateScope<bucket_number>::set(category "\0" name)
89
90 // Sets a current sampling state of the given bucket.
91 // |categoryAndName| doesn't need to be a constant string.
92 // The format of the string is "category\0name".
93 #define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, catego ryAndName) \
94 TraceEvent::SamplingStateScope<bucket_number>::set(categoryAndName)
95
96 // Get a pointer to the enabled state of the given trace category. Only
97 // long-lived literal strings should be given as the category name. The returned
98 // pointer can be held permanently in a local static for example. If the
99 // unsigned char is non-zero, tracing is enabled. If tracing is enabled,
100 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
101 // between the load of the tracing state and the call to
102 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
103 // for best performance when tracing is disabled.
104 // const unsigned char*
105 // TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
106 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
107 blink::EventTracer::getTraceCategoryEnabledFlag
108
109 // Add a trace event to the platform tracing system.
110 // blink::TraceEvent::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT(
111 // const char* name,
112 // const char* scope,
113 // unsigned long long id,
114 // double timestamp,
115 // int num_args,
116 // const char** arg_names,
117 // const unsigned char* arg_types,
118 // const unsigned long long* arg_values,
119 // std::unique_ptr<TracedValue> tracedValues[],
120 // unsigned char flags)
121 #define TRACE_EVENT_API_ADD_TRACE_EVENT \
122 blink::EventTracer::addTraceEvent
123
124 // Set the duration field of a COMPLETE trace event.
125 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
126 // blink::TraceEvent::TraceEventHandle handle)
127 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
128 blink::EventTracer::updateTraceEventDuration
129
130 ////////////////////////////////////////////////////////////////////////////////
131
132 // Implementation detail: trace event macros create temporary variables
133 // to keep instrumentation overhead low. These macros give each temporary
134 // variable a unique name based on the line number to prevent name collissions.
135 #define INTERNAL_TRACE_EVENT_UID3(a, b) \
136 trace_event_unique_##a##b
137 #define INTERNAL_TRACE_EVENT_UID2(a, b) \
138 INTERNAL_TRACE_EVENT_UID3(a, b)
139 #define INTERNALTRACEEVENTUID(name_prefix) \
140 INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
141
142 // Implementation detail: internal macro to create static category.
143 // - WTF_ANNOTATE_BENIGN_RACE, see Thread Safety above.
144
145 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \
146 static const unsigned char* INTERNALTRACEEVENTUID(categoryGroupEnabled) = 0; \
147 WTF_ANNOTATE_BENIGN_RACE(&INTERNALTRACEEVENTUID(categoryGroupEnabled), \
148 "trace_event category"); \
149 if (!INTERNALTRACEEVENTUID(categoryGroupEnabled)) { \
150 INTERNALTRACEEVENTUID(categoryGroupEnabled) = \
151 TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category); \
152 }
153
154 // Implementation detail: internal macro to create static category and add
155 // event if the category is enabled.
156 #define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
157 do { \
158 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
159 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
160 blink::TraceEvent::addTraceEvent( \
161 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
162 blink::TraceEvent::kGlobalScope, blink::TraceEvent::noEventId, \
163 flags, ##__VA_ARGS__); \
164 } \
165 } while (0)
166
167 // Implementation detail: internal macro to create static category and add begin
168 // event if the category is enabled. Also adds the end event when the scope
169 // ends.
170 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
171 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
172 blink::TraceEvent::ScopedTracer INTERNALTRACEEVENTUID(scopedTracer); \
173 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
174 blink::TraceEvent::TraceEventHandle h = \
175 blink::TraceEvent::addTraceEvent( \
176 TRACE_EVENT_PHASE_COMPLETE, \
177 INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
178 blink::TraceEvent::kGlobalScope, blink::TraceEvent::noEventId, \
179 TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
180 INTERNALTRACEEVENTUID(scopedTracer).initialize( \
181 INTERNALTRACEEVENTUID(categoryGroupEnabled), name, h); \
182 }
183
184 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category, name, bindId, flowFl ags, ...) \
185 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
186 blink::TraceEvent::ScopedTracer INTERNALTRACEEVENTUID(scopedTracer); \
187 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
188 unsigned traceEventFlags = flowFlags; \
189 blink::TraceEvent::TraceID traceEventBindId(bindId, &traceEventFlags); \
190 blink::TraceEvent::TraceEventHandle h = \
191 blink::TraceEvent::addTraceEvent( \
192 TRACE_EVENT_PHASE_COMPLETE, \
193 INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
194 blink::TraceEvent::kGlobalScope, blink::TraceEvent::noEventId, \
195 traceEventBindId.data(), \
196 EventTracer::systemTraceTime(), traceEventFlags, ##__VA_ARGS__); \
197 INTERNALTRACEEVENTUID(scopedTracer).initialize( \
198 INTERNALTRACEEVENTUID(categoryGroupEnabled), name, h); \
199 }
200
201 // Implementation detail: internal macro to create static category and add
202 // event if the category is enabled.
203 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, ...) \
204 do { \
205 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
206 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
207 unsigned traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
208 blink::TraceEvent::TraceID traceEventTraceID( \
209 id, &traceEventFlags); \
210 blink::TraceEvent::addTraceEvent( \
211 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
212 traceEventTraceID.scope(), traceEventTraceID.data(), \
213 traceEventFlags, ##__VA_ARGS__); \
214 } \
215 } while (0)
216
217
218 // Implementation detail: internal macro to create static category and add event
219 // if the category is enabled.
220 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP(phase, category, name, id , timestamp, flags, ...) \
221 do { \
222 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
223 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
224 unsigned traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
225 blink::TraceEvent::TraceID traceEventTraceID( \
226 id, &traceEventFlags); \
227 blink::TraceEvent::addTraceEvent( \
228 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
229 traceEventTraceID.scope(), traceEventTraceID.data(), \
230 blink::TraceEvent::noBindId, \
231 timestamp, traceEventFlags, ##__VA_ARGS__); \
232 } \
233 } while (0)
234
235 // Implementation detail: internal macro to create static category and add
236 // event if the category is enabled.
237 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name, timestamp , flags, ...) \
238 do { \
239 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
240 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
241 blink::TraceEvent::addTraceEvent( \
242 phase, INTERNALTRACEEVENTUID(categoryGroupEnabled), name, \
243 blink::TraceEvent::kGlobalScope, blink::TraceEvent::noEventId, \
244 blink::TraceEvent::noBindId, \
245 timestamp, flags, ##__VA_ARGS__); \
246 } \
247 } while (0)
248
249 // Implementation detail: internal macro to enter and leave a context based on
250 // the current scope.
251 #define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(categoryGroup, name, context) \
252 struct INTERNAL_TRACE_EVENT_UID(ScopedContext) { \
253 public: \
254 INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : m_cid(cid) { \
255 TRACE_EVENT_ENTER_CONTEXT(category_group, name, m_cid); \
256 } \
257 ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() { \
258 TRACE_EVENT_LEAVE_CONTEXT(category_group, name, m_cid); \
259 } \
260 private: \
261 uint64_t m_cid; \
262 INTERNAL_TRACE_EVENT_UID(ScopedContext) \
263 (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}; \
264 void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}; \
265 }; \
266 INTERNAL_TRACE_EVENT_UID(ScopedContext) \
267 INTERNAL_TRACE_EVENT_UID(scoped_context)(context.data());
268
269 // These values must be in sync with base::debug::TraceLog::CategoryGroupEnabled Flags.
270 #define INTERNAL_ENABLED_FOR_RECORDING (1 << 0)
271 #define INTERNAL_ENABLED_FOR_EVENT_CALLBACK (1 << 2)
272
273 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
274 (*INTERNALTRACEEVENTUID(categoryGroupEnabled) & (INTERNAL_ENABLED_FOR_RECORD ING | INTERNAL_ENABLED_FOR_EVENT_CALLBACK))
275
276 #define INTERNAL_TRACE_MEMORY(category, name)
277 24
278 namespace blink { 25 namespace blink {
279
280 namespace TraceEvent { 26 namespace TraceEvent {
281 27
282 // Specify these values when the corresponding argument of addTraceEvent is not 28 using base::trace_event::TraceScopedTrackableObject;
283 // used.
284 const int zeroNumArgs = 0;
285 const std::nullptr_t kGlobalScope = nullptr;
286 const unsigned long long noEventId = 0;
287 const unsigned long long noBindId = 0;
288 29
289 // TraceID encapsulates an ID that can either be an integer or pointer; 30 inline int64_t toTraceTimestamp(double seconds)
290 // optionally, it can be paired with a scope string, too. Pointers are mangled
291 // with the Process ID so that they are unlikely to collide when the same
292 // pointer is used on different processes.
293 class TraceID final {
294 STACK_ALLOCATED();
295 WTF_MAKE_NONCOPYABLE(TraceID);
296 public:
297 class WithScope final {
298 STACK_ALLOCATED();
299 public:
300 template<typename T> WithScope(const char* scope, T id)
301 : m_scope(scope), m_data(reinterpret_cast<unsigned long long>(id)) { }
302 const char* scope() const { return m_scope; }
303 unsigned long long data() const { return m_data; }
304 private:
305 const char* m_scope = kGlobalScope;
306 unsigned long long m_data;
307 };
308
309 template<bool dummyMangle> class MangleBehavior final {
310 STACK_ALLOCATED();
311 public:
312 template<typename T> explicit MangleBehavior(T id) : m_data(reinterpret_ cast<unsigned long long>(id)) { }
313 explicit MangleBehavior(WithScope scopedID) : m_scope(scopedID.scope()), m_data(scopedID.data()) { }
314 const char* scope() const { return m_scope; }
315 unsigned long long data() const { return m_data; }
316 private:
317 const char* m_scope = kGlobalScope;
318 unsigned long long m_data;
319 };
320 typedef MangleBehavior<false> DontMangle;
321 typedef MangleBehavior<true> ForceMangle;
322
323 TraceID(const void* id, unsigned* flags)
324 : m_data(static_cast<unsigned long long>(reinterpret_cast<uintptr_t>(id) ))
325 {
326 *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
327 }
328 TraceID(ForceMangle id, unsigned* flags)
329 : m_scope(id.scope()), m_data(id.data())
330 {
331 *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
332 }
333 TraceID(DontMangle id, unsigned*) : m_scope(id.scope()), m_data(id.data()) { }
334 TraceID(unsigned long long id, unsigned*) : m_data(id) { }
335 TraceID(unsigned long id, unsigned*) : m_data(id) { }
336 TraceID(unsigned id, unsigned*) : m_data(id) { }
337 TraceID(unsigned short id, unsigned*) : m_data(id) { }
338 TraceID(unsigned char id, unsigned*) : m_data(id) { }
339 TraceID(long long id, unsigned*) :
340 m_data(static_cast<unsigned long long>(id)) { }
341 TraceID(long id, unsigned*) :
342 m_data(static_cast<unsigned long long>(id)) { }
343 TraceID(int id, unsigned*) :
344 m_data(static_cast<unsigned long long>(id)) { }
345 TraceID(short id, unsigned*) :
346 m_data(static_cast<unsigned long long>(id)) { }
347 TraceID(signed char id, unsigned*) :
348 m_data(static_cast<unsigned long long>(id)) { }
349 TraceID(WithScope scopedID, unsigned*) :
350 m_scope(scopedID.scope()), m_data(scopedID.data()) { }
351
352 const char* scope() const { return m_scope; }
353 unsigned long long data() const { return m_data; }
354
355 private:
356 const char* m_scope = kGlobalScope;
357 unsigned long long m_data;
358 };
359
360 // Simple union to store various types as unsigned long long.
361 union TraceValueUnion {
362 bool m_bool;
363 unsigned long long m_uint;
364 long long m_int;
365 double m_double;
366 const void* m_pointer;
367 const char* m_string;
368 };
369
370 // Simple container for const char* that should be copied instead of retained.
371 class TraceStringWithCopy {
372 STACK_ALLOCATED();
373 public:
374 explicit TraceStringWithCopy(const char* str) : m_str(str) { }
375 const char* str() const { return m_str; }
376 private:
377 const char* m_str;
378 };
379
380 // Define setTraceValue for each allowed type. It stores the type and
381 // value in the return arguments. This allows this API to avoid declaring any
382 // structures so that it is portable to third_party libraries.
383 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actualType, argExpression, unionMember, valueTypeId) \
384 static inline void setTraceValue(actualType arg, unsigned char* type, unsign ed long long* value) { \
385 TraceValueUnion typeValue; \
386 typeValue.unionMember = argExpression; \
387 *type = valueTypeId; \
388 *value = typeValue.m_uint; \
389 }
390 // Simpler form for int types that can be safely casted.
391 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actualType, valueTypeId) \
392 static inline void setTraceValue(actualType arg, \
393 unsigned char* type, \
394 unsigned long long* value) { \
395 *type = valueTypeId; \
396 *value = static_cast<unsigned long long>(arg); \
397 }
398
399 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
400 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned, TRACE_VALUE_TYPE_UINT)
401 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
402 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
403 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
404 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
405 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
406 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
407 INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, m_bool, TRACE_VALUE_TYPE_BOOL)
408 INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, m_double, TRACE_VALUE_TYPE_DOUBLE)
409 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg, m_pointer, TRACE_VALUE_TYPE_P OINTER)
410 INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg, m_string, TRACE_VALUE_TYPE_ST RING)
411 INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, arg.str(), m_string , TRACE_VALUE_TYPE_COPY_STRING)
412
413 #undef INTERNAL_DECLARE_SET_TRACE_VALUE
414 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
415
416 // WTF::String version of setTraceValue so that trace arguments can be strings.
417 static inline void setTraceValue(const WTF::CString& arg, unsigned char* type, u nsigned long long* value)
418 { 31 {
419 TraceValueUnion typeValue; 32 return (base::TimeTicks() + base::TimeDelta::FromSecondsD(seconds)).ToIntern alValue();
420 typeValue.m_string = arg.data();
421 *type = TRACE_VALUE_TYPE_COPY_STRING;
422 *value = typeValue.m_uint;
423 } 33 }
424 34
425 static inline void setTraceValue(TracedValue*, unsigned char* type, unsigned lon g long*)
426 {
427 *type = TRACE_VALUE_TYPE_CONVERTABLE;
428 }
429
430 template<typename T> static inline void setTraceValue(const std::unique_ptr<T>& ptr, unsigned char* type, unsigned long long* value)
431 {
432 setTraceValue(ptr.get(), type, value);
433 }
434
435 template<typename T> struct TracedValueTraits {
436 static const bool isTracedValue = false;
437 static std::unique_ptr<TracedValue> moveFromIfTracedValue(const T&)
438 {
439 return nullptr;
440 }
441 };
442
443 template<typename T> struct TracedValueTraits<std::unique_ptr<T>> {
444 static const bool isTracedValue = std::is_convertible<T*, TracedValue*>::val ue;
445 static std::unique_ptr<TracedValue> moveFromIfTracedValue(std::unique_ptr<T> && tracedValue)
446 {
447 return std::move(tracedValue);
448 }
449 };
450
451 template<typename T> bool isTracedValue(const T&)
452 {
453 return TracedValueTraits<T>::isTracedValue;
454 }
455
456 template<typename T> std::unique_ptr<TracedValue> moveFromIfTracedValue(T&& valu e)
457 {
458 return TracedValueTraits<T>::moveFromIfTracedValue(std::forward<T>(value));
459 }
460
461 // These addTraceEvent template functions are defined here instead of in the
462 // macro, because the arg values could be temporary string objects. In order to
463 // store pointers to the internal c_str and pass through to the tracing API, the
464 // arg values must live throughout these procedures.
465
466 static inline TraceEventHandle addTraceEvent(
467 char phase,
468 const unsigned char* categoryEnabled,
469 const char* name,
470 const char* scope,
471 unsigned long long id,
472 unsigned long long bindId,
473 double timestamp,
474 unsigned flags)
475 {
476 return TRACE_EVENT_API_ADD_TRACE_EVENT(
477 phase, categoryEnabled, name, scope, id, bindId, timestamp,
478 zeroNumArgs, 0, 0, 0,
479 flags);
480 }
481
482 template <typename ARG1_TYPE>
483 static inline TraceEventHandle addTraceEvent(
484 char phase,
485 const unsigned char* categoryEnabled,
486 const char* name,
487 const char* scope,
488 unsigned long long id,
489 unsigned long long bindId,
490 double timestamp,
491 unsigned flags,
492 const char* arg1Name,
493 ARG1_TYPE&& arg1Val)
494 {
495 const int numArgs = 1;
496 unsigned char argTypes[1];
497 unsigned long long argValues[1];
498 setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
499 if (isTracedValue(arg1Val)) {
500 return TRACE_EVENT_API_ADD_TRACE_EVENT(
501 phase, categoryEnabled, name, scope, id, bindId, timestamp,
502 numArgs, &arg1Name, argTypes, argValues,
503 moveFromIfTracedValue(std::forward<ARG1_TYPE>(arg1Val)),
504 nullptr,
505 flags);
506 }
507 return TRACE_EVENT_API_ADD_TRACE_EVENT(
508 phase, categoryEnabled, name, scope, id, bindId, timestamp,
509 numArgs, &arg1Name, argTypes, argValues,
510 flags);
511 }
512
513 template<typename ARG1_TYPE, typename ARG2_TYPE>
514 static inline TraceEventHandle addTraceEvent(
515 char phase,
516 const unsigned char* categoryEnabled,
517 const char* name,
518 const char* scope,
519 unsigned long long id,
520 unsigned long long bindId,
521 double timestamp,
522 unsigned flags,
523 const char* arg1Name,
524 ARG1_TYPE&& arg1Val,
525 const char* arg2Name,
526 ARG2_TYPE&& arg2Val)
527 {
528 const int numArgs = 2;
529 const char* argNames[2] = { arg1Name, arg2Name };
530 unsigned char argTypes[2];
531 unsigned long long argValues[2];
532 setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
533 setTraceValue(arg2Val, &argTypes[1], &argValues[1]);
534 if (isTracedValue(arg1Val) || isTracedValue(arg2Val)) {
535 return TRACE_EVENT_API_ADD_TRACE_EVENT(
536 phase, categoryEnabled, name, scope, id, bindId, timestamp,
537 numArgs, argNames, argTypes, argValues,
538 moveFromIfTracedValue(std::forward<ARG1_TYPE>(arg1Val)),
539 moveFromIfTracedValue(std::forward<ARG2_TYPE>(arg2Val)),
540 flags);
541 }
542 return TRACE_EVENT_API_ADD_TRACE_EVENT(
543 phase, categoryEnabled, name, scope, id, bindId, timestamp,
544 numArgs, argNames, argTypes, argValues,
545 flags);
546 }
547
548 static inline TraceEventHandle addTraceEvent(
549 char phase,
550 const unsigned char* categoryEnabled,
551 const char* name,
552 const char* scope,
553 unsigned long long id,
554 unsigned flags)
555 {
556 return addTraceEvent(phase, categoryEnabled, name, scope, id,
557 blink::TraceEvent::noBindId, EventTracer::systemTraceTime(), flags);
558 }
559
560 template<typename ARG1_TYPE>
561 static inline TraceEventHandle addTraceEvent(
562 char phase,
563 const unsigned char* categoryEnabled,
564 const char* name,
565 const char* scope,
566 unsigned long long id,
567 unsigned flags,
568 const char* arg1Name,
569 ARG1_TYPE&& arg1Val)
570 {
571 return addTraceEvent(phase, categoryEnabled, name, scope, id,
572 blink::TraceEvent::noBindId, EventTracer::systemTraceTime(), flags,
573 arg1Name, std::forward<ARG1_TYPE>(arg1Val));
574 }
575
576
577 template<typename ARG1_TYPE, typename ARG2_TYPE>
578 static inline TraceEventHandle addTraceEvent(
579 char phase,
580 const unsigned char* categoryEnabled,
581 const char* name,
582 const char* scope,
583 unsigned long long id,
584 unsigned flags,
585 const char* arg1Name,
586 ARG1_TYPE&& arg1Val,
587 const char* arg2Name,
588 ARG2_TYPE&& arg2Val)
589 {
590 return addTraceEvent(phase, categoryEnabled, name, scope, id,
591 blink::TraceEvent::noBindId, EventTracer::systemTraceTime(), flags,
592 arg1Name, std::forward<ARG1_TYPE>(arg1Val),
593 arg2Name, std::forward<ARG2_TYPE>(arg2Val));
594 }
595
596 // Used by TRACE_EVENTx macro. Do not use directly.
597 class ScopedTracer final {
598 STACK_ALLOCATED();
599 WTF_MAKE_NONCOPYABLE(ScopedTracer);
600 public:
601 // Note: members of m_data intentionally left uninitialized. See initialize.
602 ScopedTracer() : m_pdata(0) { }
603 ~ScopedTracer()
604 {
605 if (m_pdata && *m_pdata->categoryGroupEnabled)
606 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(m_data.categoryGroupEnab led, m_data.name, m_data.eventHandle);
607 }
608
609 void initialize(const unsigned char* categoryGroupEnabled, const char* name, TraceEventHandle eventHandle)
610 {
611 m_data.categoryGroupEnabled = categoryGroupEnabled;
612 m_data.name = name;
613 m_data.eventHandle = eventHandle;
614 m_pdata = &m_data;
615 }
616
617 private:
618 // This Data struct workaround is to avoid initializing all the members
619 // in Data during construction of this object, since this object is always
620 // constructed, even when tracing is disabled. If the members of Data were
621 // members of this class instead, compiler warnings occur about potential
622 // uninitialized accesses.
623 struct Data {
624 DISALLOW_NEW();
625 const unsigned char* categoryGroupEnabled;
626 const char* name;
627 TraceEventHandle eventHandle;
628 };
629 Data* m_pdata;
630 Data m_data;
631 };
632
633 // TraceEventSamplingStateScope records the current sampling state
634 // and sets a new sampling state. When the scope exists, it restores
635 // the sampling state having recorded.
636 template<size_t BucketNumber>
637 class SamplingStateScope final {
638 STACK_ALLOCATED();
639 WTF_MAKE_NONCOPYABLE(SamplingStateScope);
640 public:
641 SamplingStateScope(const char* categoryAndName)
642 {
643 m_previousState = SamplingStateScope<BucketNumber>::current();
644 SamplingStateScope<BucketNumber>::set(categoryAndName);
645 }
646
647 ~SamplingStateScope()
648 {
649 SamplingStateScope<BucketNumber>::set(m_previousState);
650 }
651
652 // FIXME: Make load/store to traceSamplingState[] thread-safe and atomic.
653 static const char* current()
654 {
655 return reinterpret_cast<const char*>(*blink::traceSamplingState[BucketNu mber]);
656 }
657 static void set(const char* categoryAndName)
658 {
659 *blink::traceSamplingState[BucketNumber] = reinterpret_cast<TraceEventAP IAtomicWord>(categoryAndName);
660 }
661
662 private:
663 const char* m_previousState;
664 };
665
666 template<typename IDType> class TraceScopedTrackableObject {
667 STACK_ALLOCATED();
668 WTF_MAKE_NONCOPYABLE(TraceScopedTrackableObject);
669 public:
670 TraceScopedTrackableObject(const char* categoryGroup, const char* name, IDTy pe id)
671 : m_categoryGroup(categoryGroup), m_name(name), m_id(id)
672 {
673 TRACE_EVENT_OBJECT_CREATED_WITH_ID(m_categoryGroup, m_name, m_id);
674 }
675
676 ~TraceScopedTrackableObject()
677 {
678 TRACE_EVENT_OBJECT_DELETED_WITH_ID(m_categoryGroup, m_name, m_id);
679 }
680
681 private:
682 const char* m_categoryGroup;
683 const char* m_name;
684 IDType m_id;
685 };
686
687 } // namespace TraceEvent 35 } // namespace TraceEvent
688
689 } // namespace blink 36 } // namespace blink
690 37
691 #endif 38 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/EventTracer.cpp ('k') | third_party/WebKit/Source/platform/TraceEventCommon.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698