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

Side by Side Diff: src/tracing/trace-event.h

Issue 988893003: Implement tracing interface for v8 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Minor Created 5 years, 3 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
(Empty)
1 // Copyright 2015 the V8 project 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 SRC_TRACING_TRACE_EVENT_H_
6 #define SRC_TRACING_TRACE_EVENT_H_
7
8 // This header file defines implementation details of how the trace macros in
9 // trace_event_common.h collect and store trace events. Anything not
10 // implementation-specific should go in trace_macros_common.h instead of here.
11
12 #include "include/v8-tracing.h"
13 #include "src/tracing/trace-event-common.h"
14
15 // By default, const char* argument values are assumed to have long-lived scope
16 // and will not be copied. Use this macro to force a const char* to be copied.
17 #define TRACE_STR_COPY(str) v8::internal::tracing::TraceStringWithCopy(str)
18
19 // By default, uint64 ID argument values are not mangled with the Process ID in
20 // TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
21 #define TRACE_ID_MANGLE(id) v8::internal::tracing::TraceID::ForceMangle(id)
22
23 // By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
24 // macros. Use this macro to prevent Process ID mangling.
25 #define TRACE_ID_DONT_MANGLE(id) v8::internal::tracing::TraceID::DontMangle(id)
26
27 // Sets the current sample state to the given category and name (both must be
28 // constant strings). These states are intended for a sampling profiler.
29 // Implementation note: we store category and name together because we don't
30 // want the inconsistency/expense of storing two pointers.
31 // |thread_bucket| is [0..2] and is used to statically isolate samples in one
32 // thread from others.
33 #define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, \
34 name) \
35 v8::internal::tracing::TraceEventSamplingStateScope<bucket_number>::Set( \
36 category "\0" name)
37
38 // Returns a current sampling state of the given bucket.
39 #define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
40 v8::internal::tracing::TraceEventSamplingStateScope<bucket_number>::Current()
41
42 // Creates a scope of a sampling state of the given bucket.
43 //
44 // { // The sampling state is set within this scope.
45 // TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
46 // ...;
47 // }
48 #define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, \
49 name) \
50 trace_event_internal::TraceEventSamplingStateScope<bucket_number> \
51 traceEventSamplingScope(category "\0" name);
52
53
54 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
55 *INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \
56 (EventTracer::kEnabledForRecording_CategoryGroupEnabledFlags | \
57 EventTracer::kEnabledForEventCallback_CategoryGroupEnabledFlags)
58
59 #define INTERNAL_TRACE_MEMORY(category, name)
60
dsinclair 2015/08/25 13:56:22 Should this be UNIMPLEMENTED()?
fmeawad 2015/08/25 21:32:01 No, because it is OK for it to have no implementat
61 ////////////////////////////////////////////////////////////////////////////////
62 // Implementation specific tracing API definitions.
63
64 // Get a pointer to the enabled state of the given trace category. Only
65 // long-lived literal strings should be given as the category group. The
66 // returned pointer can be held permanently in a local static for example. If
67 // the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
68 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
69 // between the load of the tracing state and the call to
70 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
71 // for best performance when tracing is disabled.
72 // const uint8_t*
73 // TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
74 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
75 EventTracer::GetInstance()->GetCategoryGroupEnabled
76
77 // Get the number of times traces have been recorded. This is used to implement
78 // the TRACE_EVENT_IS_NEW_TRACE facility.
79 // unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED()
80 #define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED \
81 EventTracer::GetInstance()->getNumTracesRecorded
82
83 // Add a trace event to the platform tracing system.
84 // EventTracer::Handle TRACE_EVENT_API_ADD_TRACE_EVENT(
85 // char phase,
86 // const uint8_t* category_group_enabled,
87 // const char* name,
88 // uint64_t id,
89 // uint64_t context_id,
90 // uint64_t bind_id,
91 // int num_args,
92 // const char** arg_names,
93 // const uint8_t* arg_types,
94 // const uint64_t* arg_values,
95 // unsigned int flags)
96 #define TRACE_EVENT_API_ADD_TRACE_EVENT \
97 EventTracer::GetInstance()->AddTraceEvent
98
99 // Set the duration field of a COMPLETE trace event.
100 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
101 // const uint8_t* category_group_enabled,
102 // const char* name,
103 // EventTracer::Handle id)
104 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
105 EventTracer::GetInstance()->UpdateTraceEventDuration
106
107 // These operations are atomic in the Chrome tracing implementation
108 // to cater to ARM's weak memory consistency; we're just doing read/
109 // write here because it's not strictly needed for correctness.
110 // So says Nat.
111 // FIXME
dsinclair 2015/08/25 13:56:22 crbug?
fmeawad 2015/08/25 21:32:01 I fixed the implementation, was a left out of a co
112
113 #define TRACE_EVENT_API_ATOMIC_WORD intptr_t
114 #define TRACE_EVENT_API_ATOMIC_LOAD(var) (*(&var))
115 #define TRACE_EVENT_API_ATOMIC_STORE(var, value) (var = value)
116
117 // Defines visibility for classes in trace_event.h
118 // #define TRACE_EVENT_API_CLASS_EXPORT _API
119
120 // The thread buckets for the sampling profiler.
121 extern TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3];
122
123 #define TRACE_EVENT_API_THREAD_BUCKET(thread_bucket) \
124 g_trace_state[thread_bucket]
125
126 ////////////////////////////////////////////////////////////////////////////////
127
128 // Implementation detail: trace event macros create temporary variables
129 // to keep instrumentation overhead low. These macros give each temporary
130 // variable a unique name based on the line number to prevent name collisions.
131 #define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b
132 #define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b)
133 #define INTERNAL_TRACE_EVENT_UID(name_prefix) \
134 INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
135
136 // Implementation detail: internal macro to create static category.
137 // No barriers are needed, because this code is designed to operate safely
138 // even when the unsigned char* points to garbage data (which may be the case
139 // on processors without cache coherency).
140 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
141 category_group, atomic, category_group_enabled) \
142 category_group_enabled = \
143 reinterpret_cast<const uint8_t*>(TRACE_EVENT_API_ATOMIC_LOAD(atomic)); \
144 if (!category_group_enabled) { \
145 category_group_enabled = \
146 TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
147 TRACE_EVENT_API_ATOMIC_STORE( \
148 atomic, reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
149 category_group_enabled)); \
150 }
151
152 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
153 static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
154 const uint8_t* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
155 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
156 category_group, INTERNAL_TRACE_EVENT_UID(atomic), \
157 INTERNAL_TRACE_EVENT_UID(category_group_enabled));
158
159 // Implementation detail: internal macro to create static category and add
160 // event if the category is enabled.
161 #define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
162 do { \
163 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
164 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
165 v8::internal::tracing::AddTraceEvent( \
166 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
167 v8::internal::tracing::kNoId, v8::internal::tracing::kNoId, flags, \
168 ##__VA_ARGS__); \
169 } \
170 } while (0)
171
172 // Implementation detail: internal macro to create static category and add begin
173 // event if the category is enabled. Also adds the end event when the scope
174 // ends.
175 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
176 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
177 v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
178 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
179 EventTracer::Handle h = v8::internal::tracing::AddTraceEvent( \
180 TRACE_EVENT_PHASE_COMPLETE, \
181 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
182 v8::internal::tracing::kNoId, TRACE_EVENT_FLAG_NONE, \
183 v8::internal::tracing::kNoId, ##__VA_ARGS__); \
184 INTERNAL_TRACE_EVENT_UID(tracer) \
185 .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
186 h); \
187 }
188
189 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \
190 bind_id, flow_flags, ...) \
191 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
192 v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
193 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
194 unsigned int trace_event_flags = flow_flags; \
195 v8::internal::tracing::TraceID trace_event_bind_id(bind_id, \
196 &trace_event_flags); \
197 EventTracer::Handle h = v8::internal::tracing::AddTraceEvent( \
198 TRACE_EVENT_PHASE_COMPLETE, \
199 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
200 v8::internal::tracing::kNoId, trace_event_bind_id.data(), \
201 trace_event_flags, ##__VA_ARGS__); \
202 INTERNAL_TRACE_EVENT_UID(tracer) \
203 .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
204 h); \
205 }
206
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_ID(phase, category_group, name, id, \
210 flags, ...) \
211 do { \
212 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
213 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
214 unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
215 v8::internal::tracing::TraceID trace_event_trace_id(id, \
216 &trace_event_flags); \
217 v8::internal::tracing::AddTraceEvent( \
218 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
219 trace_event_trace_id.data(), v8::internal::tracing::kNoId, \
220 trace_event_flags, ##__VA_ARGS__); \
221 } \
222 } while (0)
223
224 // Adds a trace event with a given timestamp. Not Implemented.
225 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
226 timestamp, flags, ...) \
227 UNIMPLEMENTED()
228
229 // Adds a trace event with a given id and timestamp. Not Implemented.
230 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP( \
231 phase, category_group, name, id, timestamp, flags, ...) \
232 UNIMPLEMENTED()
233
234 // Adds a trace event with a given id, thread_id, and timestamp. Not
235 // Implemented.
236 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
237 phase, category_group, name, id, thread_id, timestamp, flags, ...) \
238 UNIMPLEMENTED()
239
240
241 #ifndef INTERNAL_GET_TRACE_CONTEXT_ID
242 #define INTERNAL_GET_TRACE_CONTEXT_ID \
243 (uint64_t) v8::internal::Isolate::UnsafeCurrent
244 #endif
245
246 namespace v8 {
247 namespace internal {
248 namespace tracing {
249
250 // Specify these values when the corresponding argument of AddTraceEvent is not
251 // used.
252 const int kZeroNumArgs = 0;
253 const uint64_t kNoId = 0;
254
255 // TraceID encapsulates an ID that can either be an integer or pointer. Pointers
256 // are by default mangled with the Process ID so that they are unlikely to
257 // collide when the same pointer is used on different processes.
258 class TraceID {
259 public:
260 class DontMangle {
261 public:
262 explicit DontMangle(const void* id)
263 : data_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(id))) {}
264 explicit DontMangle(uint64_t id) : data_(id) {}
265 explicit DontMangle(unsigned int id) : data_(id) {}
266 explicit DontMangle(uint16_t id) : data_(id) {}
267 explicit DontMangle(unsigned char id) : data_(id) {}
268 explicit DontMangle(int64_t id) : data_(static_cast<uint64_t>(id)) {}
269 explicit DontMangle(int id) : data_(static_cast<uint64_t>(id)) {}
270 explicit DontMangle(int16_t id) : data_(static_cast<uint64_t>(id)) {}
271 explicit DontMangle(signed char id) : data_(static_cast<uint64_t>(id)) {}
272 uint64_t data() const { return data_; }
273
274 private:
275 uint64_t data_;
276 };
277
278 class ForceMangle {
279 public:
280 explicit ForceMangle(uint64_t id) : data_(id) {}
281 explicit ForceMangle(unsigned int id) : data_(id) {}
282 explicit ForceMangle(uint16_t id) : data_(id) {}
283 explicit ForceMangle(unsigned char id) : data_(id) {}
284 explicit ForceMangle(int64_t id) : data_(static_cast<uint64_t>(id)) {}
285 explicit ForceMangle(int id) : data_(static_cast<uint64_t>(id)) {}
286 explicit ForceMangle(int16_t id) : data_(static_cast<uint64_t>(id)) {}
287 explicit ForceMangle(signed char id) : data_(static_cast<uint64_t>(id)) {}
288 uint64_t data() const { return data_; }
289
290 private:
291 uint64_t data_;
292 };
293
294 TraceID(const void* id, unsigned int* flags)
295 : data_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(id))) {
296 *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
297 }
298 TraceID(ForceMangle id, unsigned int* flags) : data_(id.data()) {
299 *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
300 }
301 TraceID(DontMangle id, unsigned int* flags) : data_(id.data()) {}
302 TraceID(uint64_t id, unsigned int* flags) : data_(id) { (void)flags; }
303 TraceID(unsigned int id, unsigned int* flags) : data_(id) { (void)flags; }
304 TraceID(uint16_t id, unsigned int* flags) : data_(id) { (void)flags; }
305 TraceID(unsigned char id, unsigned int* flags) : data_(id) { (void)flags; }
306 TraceID(int64_t id, unsigned int* flags) : data_(static_cast<uint64_t>(id)) {
307 (void)flags;
308 }
309 TraceID(int id, unsigned int* flags) : data_(static_cast<uint64_t>(id)) {
310 (void)flags;
311 }
312 TraceID(int16_t id, unsigned int* flags) : data_(static_cast<uint64_t>(id)) {
313 (void)flags;
314 }
315 TraceID(signed char id, unsigned int* flags)
316 : data_(static_cast<uint64_t>(id)) {
317 (void)flags;
318 }
319
320 uint64_t data() const { return data_; }
321
322 private:
323 uint64_t data_;
324 };
325
326 // Simple union to store various types as uint64_t.
327 union TraceValueUnion {
328 bool as_bool;
329 uint64_t as_uint;
330 int64_t as_int;
331 double as_double;
332 const void* as_pointer;
333 const char* as_string;
334 };
335
336 // Simple container for const char* that should be copied instead of retained.
337 class TraceStringWithCopy {
338 public:
339 explicit TraceStringWithCopy(const char* str) : str_(str) {}
340 operator const char*() const { return str_; }
341
342 private:
343 const char* str_;
344 };
345
346 // Define SetTraceValue for each allowed type. It stores the type and
347 // value in the return arguments. This allows this API to avoid declaring any
348 // structures so that it is portable to third_party libraries.
349 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member, \
350 value_type_id) \
351 static inline void SetTraceValue(actual_type arg, unsigned char* type, \
352 uint64_t* value) { \
353 TraceValueUnion type_value; \
354 type_value.union_member = arg; \
355 *type = value_type_id; \
356 *value = type_value.as_uint; \
357 }
358 // Simpler form for int types that can be safely casted.
359 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id) \
360 static inline void SetTraceValue(actual_type arg, unsigned char* type, \
361 uint64_t* value) { \
362 *type = value_type_id; \
363 *value = static_cast<uint64_t>(arg); \
364 }
365
366 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint64_t, TRACE_VALUE_TYPE_UINT)
367 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
368 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint16_t, TRACE_VALUE_TYPE_UINT)
369 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
370 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int64_t, TRACE_VALUE_TYPE_INT)
371 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
372 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int16_t, TRACE_VALUE_TYPE_INT)
373 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
374 INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL)
375 INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE)
376 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
377 TRACE_VALUE_TYPE_POINTER)
378 INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string,
379 TRACE_VALUE_TYPE_STRING)
380 INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string,
381 TRACE_VALUE_TYPE_COPY_STRING)
382
383 #undef INTERNAL_DECLARE_SET_TRACE_VALUE
384 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
385
386 // These AddTraceEvent template
387 // function is defined here instead of in the macro, because the arg_values
388 // could be temporary objects, such as std::string. In order to store
389 // pointers to the internal c_str and pass through to the tracing API,
390 // the arg_values must live throughout these procedures.
391
392 static inline EventTracer::Handle AddTraceEvent(
393 char phase, const uint8_t* category_group_enabled, const char* name,
394 uint64_t id, uint64_t bind_id, unsigned int flags) {
395 return TRACE_EVENT_API_ADD_TRACE_EVENT(
396 phase, category_group_enabled, name, id, INTERNAL_GET_TRACE_CONTEXT_ID(),
397 bind_id, kZeroNumArgs, NULL, NULL, NULL,
398 flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
399 }
400
401 template <class ARG1_TYPE>
402 static inline EventTracer::Handle AddTraceEvent(
403 char phase, const uint8_t* category_group_enabled, const char* name,
404 uint64_t id, uint64_t bind_id, unsigned int flags, const char* arg1_name,
405 const ARG1_TYPE& arg1_val) {
406 const int num_args = 1;
407 uint8_t arg_types[1];
408 uint64_t arg_values[1];
409 SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
410 return TRACE_EVENT_API_ADD_TRACE_EVENT(
411 phase, category_group_enabled, name, id, INTERNAL_GET_TRACE_CONTEXT_ID(),
412 bind_id, num_args, &arg1_name, arg_types, arg_values,
413 flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
414 }
415
416 template <class ARG1_TYPE, class ARG2_TYPE>
417 static inline EventTracer::Handle AddTraceEvent(
418 char phase, const uint8_t* category_group_enabled, const char* name,
419 uint64_t id, uint64_t bind_id, unsigned int flags, const char* arg1_name,
420 const ARG1_TYPE& arg1_val, const char* arg2_name,
421 const ARG2_TYPE& arg2_val) {
422 const int num_args = 2;
423 const char* arg_names[2] = {arg1_name, arg2_name};
424 unsigned char arg_types[2];
425 uint64_t arg_values[2];
426 SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
427 SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
428 return TRACE_EVENT_API_ADD_TRACE_EVENT(
429 phase, category_group_enabled, name, id, INTERNAL_GET_TRACE_CONTEXT_ID(),
430 bind_id, num_args, arg_names, arg_types, arg_values,
431 flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
432 }
433
434 // Used by TRACE_EVENTx macros. Do not use directly.
435 class ScopedTracer {
436 public:
437 // Note: members of data_ intentionally left uninitialized. See Initialize.
438 ScopedTracer() : p_data_(NULL) {}
439
440 ~ScopedTracer() {
441 if (p_data_ && *data_.category_group_enabled)
442 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
443 data_.category_group_enabled, data_.name, data_.event_handle);
444 }
445
446 void Initialize(const uint8_t* category_group_enabled, const char* name,
447 EventTracer::Handle event_handle) {
448 data_.category_group_enabled = category_group_enabled;
449 data_.name = name;
450 data_.event_handle = event_handle;
451 p_data_ = &data_;
452 }
453
454 private:
455 // This Data struct workaround is to avoid initializing all the members
456 // in Data during construction of this object, since this object is always
457 // constructed, even when tracing is disabled. If the members of Data were
458 // members of this class instead, compiler warnings occur about potential
459 // uninitialized accesses.
460 struct Data {
461 const uint8_t* category_group_enabled;
462 const char* name;
463 EventTracer::Handle event_handle;
464 };
465 Data* p_data_;
466 Data data_;
467 };
468
469 // Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
470 class ScopedTraceBinaryEfficient {
471 public:
472 ScopedTraceBinaryEfficient(const char* category_group, const char* name);
473 ~ScopedTraceBinaryEfficient();
474
475 private:
476 const uint8_t* category_group_enabled_;
477 const char* name_;
478 EventTracer::Handle event_handle_;
479 };
480
481 // TraceEventSamplingStateScope records the current sampling state
482 // and sets a new sampling state. When the scope exists, it restores
483 // the sampling state having recorded.
484 template <size_t BucketNumber>
485 class TraceEventSamplingStateScope {
486 public:
487 explicit TraceEventSamplingStateScope(const char* category_and_name) {
488 previous_state_ = TraceEventSamplingStateScope<BucketNumber>::Current();
489 TraceEventSamplingStateScope<BucketNumber>::Set(category_and_name);
490 }
491
492 ~TraceEventSamplingStateScope() {
493 TraceEventSamplingStateScope<BucketNumber>::Set(previous_state_);
494 }
495
496 static inline const char* Current() {
497 return reinterpret_cast<const char*>(
498 TRACE_EVENT_API_ATOMIC_LOAD(g_trace_state[BucketNumber]));
499 }
500
501 static inline void Set(const char* category_and_name) {
502 TRACE_EVENT_API_ATOMIC_STORE(g_trace_state[BucketNumber],
503 reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(
504 const_cast<char*>(category_and_name)));
505 }
506
507 private:
508 const char* previous_state_;
509 };
510
511 } // namespace tracing
512 } // namespace internal
513 } // namespace v8
514
515 #endif // SRC_TRACING_TRACE_EVENT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698