GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
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 |
#include "v8-platform.h" |
||
9 |
#include "tracing/agent.h" |
||
10 |
#include "trace_event_common.h" |
||
11 |
#include <atomic> |
||
12 |
|||
13 |
// This header file defines implementation details of how the trace macros in |
||
14 |
// trace_event_common.h collect and store trace events. Anything not |
||
15 |
// implementation-specific should go in trace_macros_common.h instead of here. |
||
16 |
|||
17 |
|||
18 |
// The pointer returned from GetCategoryGroupEnabled() points to a |
||
19 |
// value with zero or more of the following bits. Used in this class only. |
||
20 |
// The TRACE_EVENT macros should only use the value as a bool. |
||
21 |
// These values must be in sync with macro values in trace_log.h in |
||
22 |
// chromium. |
||
23 |
enum CategoryGroupEnabledFlags { |
||
24 |
// Category group enabled for the recording mode. |
||
25 |
kEnabledForRecording_CategoryGroupEnabledFlags = 1 << 0, |
||
26 |
// Category group enabled by SetEventCallbackEnabled(). |
||
27 |
kEnabledForEventCallback_CategoryGroupEnabledFlags = 1 << 2, |
||
28 |
// Category group enabled to export events to ETW. |
||
29 |
kEnabledForETWExport_CategoryGroupEnabledFlags = 1 << 3, |
||
30 |
}; |
||
31 |
|||
32 |
// By default, const char* argument values are assumed to have long-lived scope |
||
33 |
// and will not be copied. Use this macro to force a const char* to be copied. |
||
34 |
#define TRACE_STR_COPY(str) node::tracing::TraceStringWithCopy(str) |
||
35 |
|||
36 |
// By default, uint64 ID argument values are not mangled with the Process ID in |
||
37 |
// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling. |
||
38 |
#define TRACE_ID_MANGLE(id) node::tracing::TraceID::ForceMangle(id) |
||
39 |
|||
40 |
// By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC |
||
41 |
// macros. Use this macro to prevent Process ID mangling. |
||
42 |
#define TRACE_ID_DONT_MANGLE(id) node::tracing::TraceID::DontMangle(id) |
||
43 |
|||
44 |
// By default, trace IDs are eventually converted to a single 64-bit number. Use |
||
45 |
// this macro to add a scope string. |
||
46 |
#define TRACE_ID_WITH_SCOPE(scope, id) \ |
||
47 |
trace_event_internal::TraceID::WithScope(scope, id) |
||
48 |
|||
49 |
#define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \ |
||
50 |
*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \ |
||
51 |
(kEnabledForRecording_CategoryGroupEnabledFlags | \ |
||
52 |
kEnabledForEventCallback_CategoryGroupEnabledFlags) |
||
53 |
|||
54 |
// The following macro has no implementation, but it needs to exist since |
||
55 |
// it gets called from scoped trace events. It cannot call UNIMPLEMENTED() |
||
56 |
// since an empty implementation is a valid one. |
||
57 |
#define INTERNAL_TRACE_MEMORY(category, name) |
||
58 |
|||
59 |
//////////////////////////////////////////////////////////////////////////////// |
||
60 |
// Implementation specific tracing API definitions. |
||
61 |
|||
62 |
// Get a pointer to the enabled state of the given trace category. Only |
||
63 |
// long-lived literal strings should be given as the category group. The |
||
64 |
// returned pointer can be held permanently in a local static for example. If |
||
65 |
// the unsigned char is non-zero, tracing is enabled. If tracing is enabled, |
||
66 |
// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled |
||
67 |
// between the load of the tracing state and the call to |
||
68 |
// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out |
||
69 |
// for best performance when tracing is disabled. |
||
70 |
// const uint8_t* |
||
71 |
// TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group) |
||
72 |
#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \ |
||
73 |
node::tracing::TraceEventHelper::GetCategoryGroupEnabled |
||
74 |
|||
75 |
// Get the number of times traces have been recorded. This is used to implement |
||
76 |
// the TRACE_EVENT_IS_NEW_TRACE facility. |
||
77 |
// unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED() |
||
78 |
#define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED UNIMPLEMENTED() |
||
79 |
|||
80 |
// Add a trace event to the platform tracing system. |
||
81 |
// uint64_t TRACE_EVENT_API_ADD_TRACE_EVENT( |
||
82 |
// char phase, |
||
83 |
// const uint8_t* category_group_enabled, |
||
84 |
// const char* name, |
||
85 |
// const char* scope, |
||
86 |
// uint64_t id, |
||
87 |
// uint64_t bind_id, |
||
88 |
// int num_args, |
||
89 |
// const char** arg_names, |
||
90 |
// const uint8_t* arg_types, |
||
91 |
// const uint64_t* arg_values, |
||
92 |
// unsigned int flags) |
||
93 |
#define TRACE_EVENT_API_ADD_TRACE_EVENT node::tracing::AddTraceEventImpl |
||
94 |
|||
95 |
// Add a trace event to the platform tracing system. |
||
96 |
// uint64_t TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( |
||
97 |
// char phase, |
||
98 |
// const uint8_t* category_group_enabled, |
||
99 |
// const char* name, |
||
100 |
// const char* scope, |
||
101 |
// uint64_t id, |
||
102 |
// uint64_t bind_id, |
||
103 |
// int num_args, |
||
104 |
// const char** arg_names, |
||
105 |
// const uint8_t* arg_types, |
||
106 |
// const uint64_t* arg_values, |
||
107 |
// unsigned int flags, |
||
108 |
// int64_t timestamp) |
||
109 |
#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP \ |
||
110 |
node::tracing::AddTraceEventWithTimestampImpl |
||
111 |
|||
112 |
// Set the duration field of a COMPLETE trace event. |
||
113 |
// void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( |
||
114 |
// const uint8_t* category_group_enabled, |
||
115 |
// const char* name, |
||
116 |
// uint64_t id) |
||
117 |
#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \ |
||
118 |
if (auto controller = \ |
||
119 |
node::tracing::TraceEventHelper::GetTracingController()) \ |
||
120 |
controller->UpdateTraceEventDuration |
||
121 |
|||
122 |
// Adds a metadata event to the trace log. The |AppendValueAsTraceFormat| method |
||
123 |
// on the convertable value will be called at flush time. |
||
124 |
// TRACE_EVENT_API_ADD_METADATA_EVENT( |
||
125 |
// const unsigned char* category_group_enabled, |
||
126 |
// const char* event_name, |
||
127 |
// const char* arg_name, |
||
128 |
// std::unique_ptr<ConvertableToTraceFormat> arg_value) |
||
129 |
#define TRACE_EVENT_API_ADD_METADATA_EVENT node::tracing::AddMetadataEvent |
||
130 |
|||
131 |
// Defines atomic operations used internally by the tracing system. |
||
132 |
#define TRACE_EVENT_API_ATOMIC_WORD std::atomic<intptr_t> |
||
133 |
#define TRACE_EVENT_API_ATOMIC_WORD_VALUE intptr_t |
||
134 |
#define TRACE_EVENT_API_ATOMIC_LOAD(var) (var).load() |
||
135 |
#define TRACE_EVENT_API_ATOMIC_STORE(var, value) (var).store(value) |
||
136 |
|||
137 |
//////////////////////////////////////////////////////////////////////////////// |
||
138 |
|||
139 |
// Implementation detail: trace event macros create temporary variables |
||
140 |
// to keep instrumentation overhead low. These macros give each temporary |
||
141 |
// variable a unique name based on the line number to prevent name collisions. |
||
142 |
#define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b |
||
143 |
#define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b) |
||
144 |
#define INTERNAL_TRACE_EVENT_UID(name_prefix) \ |
||
145 |
INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) |
||
146 |
|||
147 |
// Implementation detail: internal macro to create static category. |
||
148 |
// No barriers are needed, because this code is designed to operate safely |
||
149 |
// even when the unsigned char* points to garbage data (which may be the case |
||
150 |
// on processors without cache coherency). |
||
151 |
// TODO(fmeawad): This implementation contradicts that we can have a different |
||
152 |
// configuration for each isolate, |
||
153 |
// https://code.google.com/p/v8/issues/detail?id=4563 |
||
154 |
#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \ |
||
155 |
category_group, atomic, category_group_enabled) \ |
||
156 |
category_group_enabled = \ |
||
157 |
reinterpret_cast<const uint8_t*>(TRACE_EVENT_API_ATOMIC_LOAD(atomic)); \ |
||
158 |
if (!category_group_enabled) { \ |
||
159 |
category_group_enabled = \ |
||
160 |
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \ |
||
161 |
TRACE_EVENT_API_ATOMIC_STORE( \ |
||
162 |
atomic, reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD_VALUE>( \ |
||
163 |
category_group_enabled)); \ |
||
164 |
} |
||
165 |
|||
166 |
#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \ |
||
167 |
static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) {0}; \ |
||
168 |
const uint8_t* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \ |
||
169 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \ |
||
170 |
category_group, INTERNAL_TRACE_EVENT_UID(atomic), \ |
||
171 |
INTERNAL_TRACE_EVENT_UID(category_group_enabled)); |
||
172 |
|||
173 |
// Implementation detail: internal macro to create static category and add |
||
174 |
// event if the category is enabled. |
||
175 |
#define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \ |
||
176 |
do { \ |
||
177 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
178 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
179 |
node::tracing::AddTraceEvent( \ |
||
180 |
phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
181 |
node::tracing::kGlobalScope, node::tracing::kNoId, \ |
||
182 |
node::tracing::kNoId, flags, ##__VA_ARGS__); \ |
||
183 |
} \ |
||
184 |
} while (0) |
||
185 |
|||
186 |
// Implementation detail: internal macro to create static category and add begin |
||
187 |
// event if the category is enabled. Also adds the end event when the scope |
||
188 |
// ends. |
||
189 |
#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \ |
||
190 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
191 |
node::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ |
||
192 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
193 |
uint64_t h = node::tracing::AddTraceEvent( \ |
||
194 |
TRACE_EVENT_PHASE_COMPLETE, \ |
||
195 |
INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
196 |
node::tracing::kGlobalScope, node::tracing::kNoId, \ |
||
197 |
node::tracing::kNoId, TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \ |
||
198 |
INTERNAL_TRACE_EVENT_UID(tracer) \ |
||
199 |
.Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
200 |
h); \ |
||
201 |
} |
||
202 |
|||
203 |
#define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \ |
||
204 |
bind_id, flow_flags, ...) \ |
||
205 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
206 |
node::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ |
||
207 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
208 |
unsigned int trace_event_flags = flow_flags; \ |
||
209 |
node::tracing::TraceID trace_event_bind_id(bind_id, \ |
||
210 |
&trace_event_flags); \ |
||
211 |
uint64_t h = node::tracing::AddTraceEvent( \ |
||
212 |
TRACE_EVENT_PHASE_COMPLETE, \ |
||
213 |
INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
214 |
node::tracing::kGlobalScope, node::tracing::kNoId, \ |
||
215 |
trace_event_bind_id.raw_id(), trace_event_flags, ##__VA_ARGS__); \ |
||
216 |
INTERNAL_TRACE_EVENT_UID(tracer) \ |
||
217 |
.Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
218 |
h); \ |
||
219 |
} |
||
220 |
|||
221 |
// Implementation detail: internal macro to create static category and add |
||
222 |
// event if the category is enabled. |
||
223 |
#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \ |
||
224 |
flags, ...) \ |
||
225 |
do { \ |
||
226 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
227 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
228 |
unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \ |
||
229 |
node::tracing::TraceID trace_event_trace_id(id, \ |
||
230 |
&trace_event_flags); \ |
||
231 |
node::tracing::AddTraceEvent( \ |
||
232 |
phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
233 |
trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \ |
||
234 |
node::tracing::kNoId, trace_event_flags, ##__VA_ARGS__); \ |
||
235 |
} \ |
||
236 |
} while (0) |
||
237 |
|||
238 |
// Adds a trace event with a given timestamp. |
||
239 |
#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \ |
||
240 |
timestamp, flags, ...) \ |
||
241 |
do { \ |
||
242 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
243 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
244 |
node::tracing::AddTraceEventWithTimestamp( \ |
||
245 |
phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
246 |
node::tracing::kGlobalScope, node::tracing::kNoId, \ |
||
247 |
node::tracing::kNoId, flags, timestamp, ##__VA_ARGS__); \ |
||
248 |
} \ |
||
249 |
} while (0) |
||
250 |
|||
251 |
// Adds a trace event with a given id and timestamp. Not Implemented. |
||
252 |
#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP( \ |
||
253 |
phase, category_group, name, id, timestamp, flags, ...) \ |
||
254 |
UNIMPLEMENTED() |
||
255 |
|||
256 |
// Adds a trace event with a given id, thread_id, and timestamp. Not |
||
257 |
// Implemented. |
||
258 |
#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ |
||
259 |
phase, category_group, name, id, thread_id, timestamp, flags, ...) \ |
||
260 |
do { \ |
||
261 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
262 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
263 |
unsigned int trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \ |
||
264 |
node::tracing::TraceID trace_event_trace_id(id, \ |
||
265 |
&trace_event_flags); \ |
||
266 |
node::tracing::AddTraceEventWithTimestamp( \ |
||
267 |
phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
268 |
trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \ |
||
269 |
node::tracing::kNoId, trace_event_flags, timestamp, ##__VA_ARGS__);\ |
||
270 |
} \ |
||
271 |
} while (0) |
||
272 |
|||
273 |
#define INTERNAL_TRACE_EVENT_METADATA_ADD(category_group, name, ...) \ |
||
274 |
do { \ |
||
275 |
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ |
||
276 |
if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ |
||
277 |
TRACE_EVENT_API_ADD_METADATA_EVENT( \ |
||
278 |
INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ |
||
279 |
##__VA_ARGS__); \ |
||
280 |
} \ |
||
281 |
} while(0) |
||
282 |
|||
283 |
// Enter and leave a context based on the current scope. |
||
284 |
#define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \ |
||
285 |
struct INTERNAL_TRACE_EVENT_UID(ScopedContext) { \ |
||
286 |
public: \ |
||
287 |
INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) { \ |
||
288 |
TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_); \ |
||
289 |
} \ |
||
290 |
~INTERNAL_TRACE_EVENT_UID(ScopedContext)() { \ |
||
291 |
TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_); \ |
||
292 |
} \ |
||
293 |
\ |
||
294 |
private: \ |
||
295 |
/* Local class friendly DISALLOW_COPY_AND_ASSIGN */ \ |
||
296 |
INTERNAL_TRACE_EVENT_UID(ScopedContext) \ |
||
297 |
(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {} \ |
||
298 |
void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {} \ |
||
299 |
uint64_t cid_; \ |
||
300 |
}; \ |
||
301 |
INTERNAL_TRACE_EVENT_UID(ScopedContext) \ |
||
302 |
INTERNAL_TRACE_EVENT_UID(scoped_context)(context); |
||
303 |
|||
304 |
namespace node { |
||
305 |
namespace tracing { |
||
306 |
|||
307 |
// Specify these values when the corresponding argument of AddTraceEvent is not |
||
308 |
// used. |
||
309 |
const int kZeroNumArgs = 0; |
||
310 |
const decltype(nullptr) kGlobalScope = nullptr; |
||
311 |
const uint64_t kNoId = 0; |
||
312 |
|||
313 |
class TraceEventHelper { |
||
314 |
public: |
||
315 |
static v8::TracingController* GetTracingController(); |
||
316 |
static void SetTracingController(v8::TracingController* controller); |
||
317 |
|||
318 |
static Agent* GetAgent(); |
||
319 |
static void SetAgent(Agent* agent); |
||
320 |
|||
321 |
1859185 |
static inline const uint8_t* GetCategoryGroupEnabled(const char* group) { |
|
322 |
1859185 |
v8::TracingController* controller = GetTracingController(); |
|
323 |
static const uint8_t disabled = 0; |
||
324 |
✓✓ | 1859185 |
if (UNLIKELY(controller == nullptr)) return &disabled; |
325 |
1859184 |
return controller->GetCategoryGroupEnabled(group); |
|
326 |
} |
||
327 |
}; |
||
328 |
|||
329 |
// TraceID encapsulates an ID that can either be an integer or pointer. Pointers |
||
330 |
// are by default mangled with the Process ID so that they are unlikely to |
||
331 |
// collide when the same pointer is used on different processes. |
||
332 |
class TraceID { |
||
333 |
public: |
||
334 |
class WithScope { |
||
335 |
public: |
||
336 |
WithScope(const char* scope, uint64_t raw_id) |
||
337 |
: scope_(scope), raw_id_(raw_id) {} |
||
338 |
uint64_t raw_id() const { return raw_id_; } |
||
339 |
const char* scope() const { return scope_; } |
||
340 |
|||
341 |
private: |
||
342 |
const char* scope_ = nullptr; |
||
343 |
uint64_t raw_id_; |
||
344 |
}; |
||
345 |
|||
346 |
class DontMangle { |
||
347 |
public: |
||
348 |
explicit DontMangle(const void* raw_id) |
||
349 |
: raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {} |
||
350 |
explicit DontMangle(uint64_t raw_id) : raw_id_(raw_id) {} |
||
351 |
explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {} |
||
352 |
explicit DontMangle(uint16_t raw_id) : raw_id_(raw_id) {} |
||
353 |
explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {} |
||
354 |
explicit DontMangle(int64_t raw_id) |
||
355 |
: raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
356 |
explicit DontMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
357 |
explicit DontMangle(int16_t raw_id) |
||
358 |
: raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
359 |
explicit DontMangle(signed char raw_id) |
||
360 |
: raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
361 |
explicit DontMangle(WithScope scoped_id) |
||
362 |
: scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {} |
||
363 |
const char* scope() const { return scope_; } |
||
364 |
uint64_t raw_id() const { return raw_id_; } |
||
365 |
|||
366 |
private: |
||
367 |
const char* scope_ = nullptr; |
||
368 |
uint64_t raw_id_; |
||
369 |
}; |
||
370 |
|||
371 |
class ForceMangle { |
||
372 |
public: |
||
373 |
explicit ForceMangle(uint64_t raw_id) : raw_id_(raw_id) {} |
||
374 |
explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {} |
||
375 |
explicit ForceMangle(uint16_t raw_id) : raw_id_(raw_id) {} |
||
376 |
explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {} |
||
377 |
explicit ForceMangle(int64_t raw_id) |
||
378 |
: raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
379 |
explicit ForceMangle(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
380 |
explicit ForceMangle(int16_t raw_id) |
||
381 |
: raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
382 |
explicit ForceMangle(signed char raw_id) |
||
383 |
: raw_id_(static_cast<uint64_t>(raw_id)) {} |
||
384 |
uint64_t raw_id() const { return raw_id_; } |
||
385 |
|||
386 |
private: |
||
387 |
uint64_t raw_id_; |
||
388 |
}; |
||
389 |
|||
390 |
119 |
TraceID(const void* raw_id, unsigned int* flags) |
|
391 |
119 |
: raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) { |
|
392 |
119 |
*flags |= TRACE_EVENT_FLAG_MANGLE_ID; |
|
393 |
119 |
} |
|
394 |
TraceID(ForceMangle raw_id, unsigned int* flags) : raw_id_(raw_id.raw_id()) { |
||
395 |
*flags |= TRACE_EVENT_FLAG_MANGLE_ID; |
||
396 |
} |
||
397 |
TraceID(DontMangle maybe_scoped_id, unsigned int* flags) |
||
398 |
: scope_(maybe_scoped_id.scope()), raw_id_(maybe_scoped_id.raw_id()) {} |
||
399 |
TraceID(uint64_t raw_id, unsigned int* flags) : raw_id_(raw_id) { |
||
400 |
(void)flags; |
||
401 |
} |
||
402 |
TraceID(unsigned int raw_id, unsigned int* flags) : raw_id_(raw_id) { |
||
403 |
(void)flags; |
||
404 |
} |
||
405 |
TraceID(uint16_t raw_id, unsigned int* flags) : raw_id_(raw_id) { |
||
406 |
(void)flags; |
||
407 |
} |
||
408 |
TraceID(unsigned char raw_id, unsigned int* flags) : raw_id_(raw_id) { |
||
409 |
(void)flags; |
||
410 |
} |
||
411 |
74 |
TraceID(int64_t raw_id, unsigned int* flags) |
|
412 |
74 |
: raw_id_(static_cast<uint64_t>(raw_id)) { |
|
413 |
(void)flags; |
||
414 |
74 |
} |
|
415 |
TraceID(int raw_id, unsigned int* flags) |
||
416 |
: raw_id_(static_cast<uint64_t>(raw_id)) { |
||
417 |
(void)flags; |
||
418 |
} |
||
419 |
TraceID(int16_t raw_id, unsigned int* flags) |
||
420 |
: raw_id_(static_cast<uint64_t>(raw_id)) { |
||
421 |
(void)flags; |
||
422 |
} |
||
423 |
TraceID(signed char raw_id, unsigned int* flags) |
||
424 |
: raw_id_(static_cast<uint64_t>(raw_id)) { |
||
425 |
(void)flags; |
||
426 |
} |
||
427 |
TraceID(WithScope scoped_id, unsigned int* flags) |
||
428 |
: scope_(scoped_id.scope()), raw_id_(scoped_id.raw_id()) {} |
||
429 |
|||
430 |
193 |
uint64_t raw_id() const { return raw_id_; } |
|
431 |
193 |
const char* scope() const { return scope_; } |
|
432 |
|||
433 |
private: |
||
434 |
const char* scope_ = nullptr; |
||
435 |
uint64_t raw_id_; |
||
436 |
}; |
||
437 |
|||
438 |
// Simple union to store various types as uint64_t. |
||
439 |
union TraceValueUnion { |
||
440 |
bool as_bool; |
||
441 |
uint64_t as_uint; |
||
442 |
int64_t as_int; |
||
443 |
double as_double; |
||
444 |
const void* as_pointer; |
||
445 |
const char* as_string; |
||
446 |
}; |
||
447 |
|||
448 |
// Simple container for const char* that should be copied instead of retained. |
||
449 |
class TraceStringWithCopy { |
||
450 |
public: |
||
451 |
134 |
explicit TraceStringWithCopy(const char* str) : str_(str) {} |
|
452 |
134 |
operator const char*() const { return str_; } |
|
453 |
|||
454 |
private: |
||
455 |
const char* str_; |
||
456 |
}; |
||
457 |
|||
458 |
718 |
static inline uint64_t AddTraceEventImpl( |
|
459 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
460 |
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, |
||
461 |
const char** arg_names, const uint8_t* arg_types, |
||
462 |
const uint64_t* arg_values, unsigned int flags) { |
||
463 |
✓✓ | 2154 |
std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertibles[2]; |
464 |
✓✓✓✓ |
718 |
if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) { |
465 |
25 |
arg_convertibles[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>( |
|
466 |
25 |
static_cast<intptr_t>(arg_values[0]))); |
|
467 |
} |
||
468 |
✓✓✗✓ |
718 |
if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) { |
469 |
arg_convertibles[1].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>( |
||
470 |
static_cast<intptr_t>(arg_values[1]))); |
||
471 |
} |
||
472 |
// DCHECK(num_args, 2); |
||
473 |
v8::TracingController* controller = |
||
474 |
718 |
node::tracing::TraceEventHelper::GetTracingController(); |
|
475 |
✗✓ | 718 |
if (controller == nullptr) return 0; |
476 |
718 |
return controller->AddTraceEvent(phase, category_group_enabled, name, scope, id, |
|
477 |
bind_id, num_args, arg_names, arg_types, |
||
478 |
718 |
arg_values, arg_convertibles, flags); |
|
479 |
} |
||
480 |
|||
481 |
static V8_INLINE uint64_t AddTraceEventWithTimestampImpl( |
||
482 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
483 |
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, |
||
484 |
const char** arg_names, const uint8_t* arg_types, |
||
485 |
const uint64_t* arg_values, unsigned int flags, int64_t timestamp) { |
||
486 |
✓✓ | 138 |
std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertables[2]; |
487 |
if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) { |
||
488 |
arg_convertables[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>( |
||
489 |
static_cast<intptr_t>(arg_values[0]))); |
||
490 |
} |
||
491 |
✗✓✗✗ |
46 |
if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) { |
492 |
arg_convertables[1].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>( |
||
493 |
static_cast<intptr_t>(arg_values[1]))); |
||
494 |
} |
||
495 |
// DCHECK_LE(num_args, 2); |
||
496 |
v8::TracingController* controller = |
||
497 |
46 |
node::tracing::TraceEventHelper::GetTracingController(); |
|
498 |
✗✓ | 46 |
if (controller == nullptr) return 0; |
499 |
46 |
return controller->AddTraceEventWithTimestamp( |
|
500 |
phase, category_group_enabled, name, scope, id, bind_id, num_args, |
||
501 |
46 |
arg_names, arg_types, arg_values, arg_convertables, flags, timestamp); |
|
502 |
} |
||
503 |
|||
504 |
static V8_INLINE void AddMetadataEventImpl( |
||
505 |
const uint8_t* category_group_enabled, const char* name, int32_t num_args, |
||
506 |
const char** arg_names, const uint8_t* arg_types, |
||
507 |
const uint64_t* arg_values, unsigned int flags) { |
||
508 |
✓✓✓✓ ✓✓✓✓ |
2379 |
std::unique_ptr<v8::ConvertableToTraceFormat> arg_convertibles[2]; |
509 |
✓✗✗✓ ✓✗✗✓ ✓✗✗✓ ✓✗ |
793 |
if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) { |
510 |
90 |
arg_convertibles[0].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>( |
|
511 |
90 |
static_cast<intptr_t>(arg_values[0]))); |
|
512 |
} |
||
513 |
✗✓✗✗ ✗✓✗✗ ✗✓✗✗ ✗✓✗✗ |
793 |
if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) { |
514 |
arg_convertibles[1].reset(reinterpret_cast<v8::ConvertableToTraceFormat*>( |
||
515 |
static_cast<intptr_t>(arg_values[1]))); |
||
516 |
} |
||
517 |
node::tracing::Agent* agent = |
||
518 |
793 |
node::tracing::TraceEventHelper::GetAgent(); |
|
519 |
✗✓✗✓ ✗✓✗✓ |
793 |
if (agent == nullptr) return; |
520 |
793 |
return agent->GetTracingController()->AddMetadataEvent( |
|
521 |
category_group_enabled, name, num_args, arg_names, arg_types, arg_values, |
||
522 |
arg_convertibles, flags); |
||
523 |
} |
||
524 |
|||
525 |
// Define SetTraceValue for each allowed type. It stores the type and |
||
526 |
// value in the return arguments. This allows this API to avoid declaring any |
||
527 |
// structures so that it is portable to third_party libraries. |
||
528 |
#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member, \ |
||
529 |
value_type_id) \ |
||
530 |
static inline void SetTraceValue(actual_type arg, unsigned char* type, \ |
||
531 |
uint64_t* value) { \ |
||
532 |
TraceValueUnion type_value; \ |
||
533 |
type_value.union_member = arg; \ |
||
534 |
*type = value_type_id; \ |
||
535 |
*value = type_value.as_uint; \ |
||
536 |
} |
||
537 |
// Simpler form for int types that can be safely casted. |
||
538 |
#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id) \ |
||
539 |
static inline void SetTraceValue(actual_type arg, unsigned char* type, \ |
||
540 |
uint64_t* value) { \ |
||
541 |
*type = value_type_id; \ |
||
542 |
*value = static_cast<uint64_t>(arg); \ |
||
543 |
} |
||
544 |
|||
545 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint64_t, TRACE_VALUE_TYPE_UINT) |
||
546 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT) |
||
547 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(uint16_t, TRACE_VALUE_TYPE_UINT) |
||
548 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT) |
||
549 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int64_t, TRACE_VALUE_TYPE_INT) |
||
550 |
118 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT) |
|
551 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int16_t, TRACE_VALUE_TYPE_INT) |
||
552 |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) |
||
553 |
INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL) |
||
554 |
INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE) |
||
555 |
INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer, |
||
556 |
TRACE_VALUE_TYPE_POINTER) |
||
557 |
610 |
INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string, |
|
558 |
TRACE_VALUE_TYPE_STRING) |
||
559 |
134 |
INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string, |
|
560 |
TRACE_VALUE_TYPE_COPY_STRING) |
||
561 |
|||
562 |
#undef INTERNAL_DECLARE_SET_TRACE_VALUE |
||
563 |
#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT |
||
564 |
|||
565 |
115 |
static inline void SetTraceValue(v8::ConvertableToTraceFormat* convertable_value, |
|
566 |
unsigned char* type, uint64_t* value) { |
||
567 |
115 |
*type = TRACE_VALUE_TYPE_CONVERTABLE; |
|
568 |
115 |
*value = static_cast<uint64_t>(reinterpret_cast<intptr_t>(convertable_value)); |
|
569 |
115 |
} |
|
570 |
|||
571 |
template <typename T> |
||
572 |
static inline typename std::enable_if< |
||
573 |
std::is_convertible<T*, v8::ConvertableToTraceFormat*>::value>::type |
||
574 |
115 |
SetTraceValue(std::unique_ptr<T> ptr, unsigned char* type, uint64_t* value) { |
|
575 |
115 |
SetTraceValue(ptr.release(), type, value); |
|
576 |
115 |
} |
|
577 |
|||
578 |
// These AddTraceEvent template |
||
579 |
// function is defined here instead of in the macro, because the arg_values |
||
580 |
// could be temporary objects, such as std::string. In order to store |
||
581 |
// pointers to the internal c_str and pass through to the tracing API, |
||
582 |
// the arg_values must live throughout these procedures. |
||
583 |
|||
584 |
541 |
static inline uint64_t AddTraceEvent(char phase, |
|
585 |
const uint8_t* category_group_enabled, |
||
586 |
const char* name, const char* scope, |
||
587 |
uint64_t id, uint64_t bind_id, |
||
588 |
unsigned int flags) { |
||
589 |
541 |
return TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name, |
|
590 |
scope, id, bind_id, kZeroNumArgs, |
||
591 |
541 |
nullptr, nullptr, nullptr, flags); |
|
592 |
} |
||
593 |
|||
594 |
template <class ARG1_TYPE> |
||
595 |
299 |
static inline uint64_t AddTraceEvent( |
|
596 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
597 |
const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, |
||
598 |
const char* arg1_name, ARG1_TYPE&& arg1_val) { |
||
599 |
299 |
const int num_args = 1; |
|
600 |
uint8_t arg_type; |
||
601 |
uint64_t arg_value; |
||
602 |
299 |
SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value); |
|
603 |
299 |
return TRACE_EVENT_API_ADD_TRACE_EVENT( |
|
604 |
phase, category_group_enabled, name, scope, id, bind_id, num_args, |
||
605 |
299 |
&arg1_name, &arg_type, &arg_value, flags); |
|
606 |
} |
||
607 |
|||
608 |
template <class ARG1_TYPE, class ARG2_TYPE> |
||
609 |
7 |
static inline uint64_t AddTraceEvent( |
|
610 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
611 |
const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, |
||
612 |
const char* arg1_name, ARG1_TYPE&& arg1_val, const char* arg2_name, |
||
613 |
ARG2_TYPE&& arg2_val) { |
||
614 |
7 |
const int num_args = 2; |
|
615 |
7 |
const char* arg_names[2] = {arg1_name, arg2_name}; |
|
616 |
unsigned char arg_types[2]; |
||
617 |
uint64_t arg_values[2]; |
||
618 |
7 |
SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0], |
|
619 |
&arg_values[0]); |
||
620 |
7 |
SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1], |
|
621 |
&arg_values[1]); |
||
622 |
7 |
return TRACE_EVENT_API_ADD_TRACE_EVENT( |
|
623 |
phase, category_group_enabled, name, scope, id, bind_id, num_args, |
||
624 |
7 |
arg_names, arg_types, arg_values, flags); |
|
625 |
} |
||
626 |
|||
627 |
static V8_INLINE uint64_t AddTraceEventWithTimestamp( |
||
628 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
629 |
const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, |
||
630 |
int64_t timestamp) { |
||
631 |
✗✓ | 92 |
return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( |
632 |
phase, category_group_enabled, name, scope, id, bind_id, kZeroNumArgs, |
||
633 |
nullptr, nullptr, nullptr, flags, timestamp); |
||
634 |
} |
||
635 |
|||
636 |
template <class ARG1_TYPE> |
||
637 |
static V8_INLINE uint64_t AddTraceEventWithTimestamp( |
||
638 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
639 |
const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, |
||
640 |
int64_t timestamp, const char* arg1_name, ARG1_TYPE&& arg1_val) { |
||
641 |
const int num_args = 1; |
||
642 |
uint8_t arg_type; |
||
643 |
uint64_t arg_value; |
||
644 |
SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value); |
||
645 |
return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( |
||
646 |
phase, category_group_enabled, name, scope, id, bind_id, num_args, |
||
647 |
&arg1_name, &arg_type, &arg_value, flags, timestamp); |
||
648 |
} |
||
649 |
|||
650 |
template <class ARG1_TYPE, class ARG2_TYPE> |
||
651 |
static V8_INLINE uint64_t AddTraceEventWithTimestamp( |
||
652 |
char phase, const uint8_t* category_group_enabled, const char* name, |
||
653 |
const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, |
||
654 |
int64_t timestamp, const char* arg1_name, ARG1_TYPE&& arg1_val, |
||
655 |
const char* arg2_name, ARG2_TYPE&& arg2_val) { |
||
656 |
const int num_args = 2; |
||
657 |
const char* arg_names[2] = {arg1_name, arg2_name}; |
||
658 |
unsigned char arg_types[2]; |
||
659 |
uint64_t arg_values[2]; |
||
660 |
SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_types[0], |
||
661 |
&arg_values[0]); |
||
662 |
SetTraceValue(std::forward<ARG2_TYPE>(arg2_val), &arg_types[1], |
||
663 |
&arg_values[1]); |
||
664 |
return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( |
||
665 |
phase, category_group_enabled, name, scope, id, bind_id, num_args, |
||
666 |
arg_names, arg_types, arg_values, flags, timestamp); |
||
667 |
} |
||
668 |
|||
669 |
template <class ARG1_TYPE> |
||
670 |
static V8_INLINE void AddMetadataEvent( |
||
671 |
const uint8_t* category_group_enabled, const char* name, |
||
672 |
const char* arg1_name, ARG1_TYPE&& arg1_val) { |
||
673 |
793 |
const int num_args = 1; |
|
674 |
uint8_t arg_type; |
||
675 |
uint64_t arg_value; |
||
676 |
✓✗ | 793 |
SetTraceValue(std::forward<ARG1_TYPE>(arg1_val), &arg_type, &arg_value); |
677 |
AddMetadataEventImpl( |
||
678 |
category_group_enabled, name, num_args, &arg1_name, &arg_type, &arg_value, |
||
679 |
TRACE_EVENT_FLAG_NONE); |
||
680 |
} |
||
681 |
|||
682 |
// Used by TRACE_EVENTx macros. Do not use directly. |
||
683 |
class ScopedTracer { |
||
684 |
public: |
||
685 |
// Note: members of data_ intentionally left uninitialized. See Initialize. |
||
686 |
485920 |
ScopedTracer() : p_data_(nullptr) {} |
|
687 |
|||
688 |
971736 |
~ScopedTracer() { |
|
689 |
✓✓✓✗ |
485868 |
if (p_data_ && *data_.category_group_enabled) |
690 |
✓✗ | 84 |
TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( |
691 |
84 |
data_.category_group_enabled, data_.name, data_.event_handle); |
|
692 |
485868 |
} |
|
693 |
|||
694 |
85 |
void Initialize(const uint8_t* category_group_enabled, const char* name, |
|
695 |
uint64_t event_handle) { |
||
696 |
85 |
data_.category_group_enabled = category_group_enabled; |
|
697 |
85 |
data_.name = name; |
|
698 |
85 |
data_.event_handle = event_handle; |
|
699 |
85 |
p_data_ = &data_; |
|
700 |
85 |
} |
|
701 |
|||
702 |
private: |
||
703 |
// This Data struct workaround is to avoid initializing all the members |
||
704 |
// in Data during construction of this object, since this object is always |
||
705 |
// constructed, even when tracing is disabled. If the members of Data were |
||
706 |
// members of this class instead, compiler warnings occur about potential |
||
707 |
// uninitialized accesses. |
||
708 |
struct Data { |
||
709 |
const uint8_t* category_group_enabled; |
||
710 |
const char* name; |
||
711 |
uint64_t event_handle; |
||
712 |
}; |
||
713 |
Data* p_data_; |
||
714 |
Data data_; |
||
715 |
}; |
||
716 |
|||
717 |
} // namespace tracing |
||
718 |
} // namespace node |
||
719 |
|||
720 |
#endif // SRC_TRACING_TRACE_EVENT_H_ |
Generated by: GCOVR (Version 4.2) |