1 | // Copyright 2013 The Flutter 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 | #include "flutter/fml/trace_event.h" |
6 | |
7 | #include <algorithm> |
8 | #include <atomic> |
9 | #include <utility> |
10 | |
11 | #include "flutter/fml/ascii_trie.h" |
12 | #include "flutter/fml/build_config.h" |
13 | #include "flutter/fml/logging.h" |
14 | |
15 | namespace fml { |
16 | namespace tracing { |
17 | |
18 | #if FLUTTER_TIMELINE_ENABLED |
19 | |
20 | namespace { |
21 | AsciiTrie gAllowlist; |
22 | |
23 | inline void FlutterTimelineEvent(const char* label, |
24 | int64_t timestamp0, |
25 | int64_t timestamp1_or_async_id, |
26 | Dart_Timeline_Event_Type type, |
27 | intptr_t argument_count, |
28 | const char** argument_names, |
29 | const char** argument_values) { |
30 | if (gAllowlist.Query(label)) { |
31 | Dart_TimelineEvent(label, timestamp0, timestamp1_or_async_id, type, |
32 | argument_count, argument_names, argument_values); |
33 | } |
34 | } |
35 | } // namespace |
36 | |
37 | void TraceSetAllowlist(const std::vector<std::string>& allowlist) { |
38 | gAllowlist.Fill(allowlist); |
39 | } |
40 | |
41 | size_t TraceNonce() { |
42 | static std::atomic_size_t gLastItem; |
43 | return ++gLastItem; |
44 | } |
45 | |
46 | void TraceTimelineEvent(TraceArg category_group, |
47 | TraceArg name, |
48 | int64_t timestamp_micros, |
49 | TraceIDArg identifier, |
50 | Dart_Timeline_Event_Type type, |
51 | const std::vector<const char*>& c_names, |
52 | const std::vector<std::string>& values) { |
53 | const auto argument_count = std::min(c_names.size(), values.size()); |
54 | |
55 | std::vector<const char*> c_values; |
56 | c_values.resize(argument_count, nullptr); |
57 | |
58 | for (size_t i = 0; i < argument_count; i++) { |
59 | c_values[i] = values[i].c_str(); |
60 | } |
61 | |
62 | FlutterTimelineEvent( |
63 | name, // label |
64 | timestamp_micros, // timestamp0 |
65 | identifier, // timestamp1_or_async_id |
66 | type, // event type |
67 | argument_count, // argument_count |
68 | const_cast<const char**>(c_names.data()), // argument_names |
69 | c_values.data() // argument_values |
70 | ); |
71 | } |
72 | |
73 | void TraceTimelineEvent(TraceArg category_group, |
74 | TraceArg name, |
75 | TraceIDArg identifier, |
76 | Dart_Timeline_Event_Type type, |
77 | const std::vector<const char*>& c_names, |
78 | const std::vector<std::string>& values) { |
79 | TraceTimelineEvent(category_group, // group |
80 | name, // name |
81 | Dart_TimelineGetMicros(), // timestamp_micros |
82 | identifier, // identifier |
83 | type, // type |
84 | c_names, // names |
85 | values // values |
86 | ); |
87 | } |
88 | |
89 | void TraceEvent0(TraceArg category_group, TraceArg name) { |
90 | FlutterTimelineEvent(name, // label |
91 | Dart_TimelineGetMicros(), // timestamp0 |
92 | 0, // timestamp1_or_async_id |
93 | Dart_Timeline_Event_Begin, // event type |
94 | 0, // argument_count |
95 | nullptr, // argument_names |
96 | nullptr // argument_values |
97 | ); |
98 | } |
99 | |
100 | void TraceEvent1(TraceArg category_group, |
101 | TraceArg name, |
102 | TraceArg arg1_name, |
103 | TraceArg arg1_val) { |
104 | const char* arg_names[] = {arg1_name}; |
105 | const char* arg_values[] = {arg1_val}; |
106 | FlutterTimelineEvent(name, // label |
107 | Dart_TimelineGetMicros(), // timestamp0 |
108 | 0, // timestamp1_or_async_id |
109 | Dart_Timeline_Event_Begin, // event type |
110 | 1, // argument_count |
111 | arg_names, // argument_names |
112 | arg_values // argument_values |
113 | ); |
114 | } |
115 | |
116 | void TraceEvent2(TraceArg category_group, |
117 | TraceArg name, |
118 | TraceArg arg1_name, |
119 | TraceArg arg1_val, |
120 | TraceArg arg2_name, |
121 | TraceArg arg2_val) { |
122 | const char* arg_names[] = {arg1_name, arg2_name}; |
123 | const char* arg_values[] = {arg1_val, arg2_val}; |
124 | FlutterTimelineEvent(name, // label |
125 | Dart_TimelineGetMicros(), // timestamp0 |
126 | 0, // timestamp1_or_async_id |
127 | Dart_Timeline_Event_Begin, // event type |
128 | 2, // argument_count |
129 | arg_names, // argument_names |
130 | arg_values // argument_values |
131 | ); |
132 | } |
133 | |
134 | void TraceEventEnd(TraceArg name) { |
135 | FlutterTimelineEvent(name, // label |
136 | Dart_TimelineGetMicros(), // timestamp0 |
137 | 0, // timestamp1_or_async_id |
138 | Dart_Timeline_Event_End, // event type |
139 | 0, // argument_count |
140 | nullptr, // argument_names |
141 | nullptr // argument_values |
142 | ); |
143 | } |
144 | |
145 | void TraceEventAsyncBegin0(TraceArg category_group, |
146 | TraceArg name, |
147 | TraceIDArg id) { |
148 | FlutterTimelineEvent(name, // label |
149 | Dart_TimelineGetMicros(), // timestamp0 |
150 | id, // timestamp1_or_async_id |
151 | Dart_Timeline_Event_Async_Begin, // event type |
152 | 0, // argument_count |
153 | nullptr, // argument_names |
154 | nullptr // argument_values |
155 | ); |
156 | } |
157 | |
158 | void TraceEventAsyncEnd0(TraceArg category_group, |
159 | TraceArg name, |
160 | TraceIDArg id) { |
161 | FlutterTimelineEvent(name, // label |
162 | Dart_TimelineGetMicros(), // timestamp0 |
163 | id, // timestamp1_or_async_id |
164 | Dart_Timeline_Event_Async_End, // event type |
165 | 0, // argument_count |
166 | nullptr, // argument_names |
167 | nullptr // argument_values |
168 | ); |
169 | } |
170 | |
171 | void TraceEventAsyncBegin1(TraceArg category_group, |
172 | TraceArg name, |
173 | TraceIDArg id, |
174 | TraceArg arg1_name, |
175 | TraceArg arg1_val) { |
176 | const char* arg_names[] = {arg1_name}; |
177 | const char* arg_values[] = {arg1_val}; |
178 | FlutterTimelineEvent(name, // label |
179 | Dart_TimelineGetMicros(), // timestamp0 |
180 | id, // timestamp1_or_async_id |
181 | Dart_Timeline_Event_Async_Begin, // event type |
182 | 1, // argument_count |
183 | arg_names, // argument_names |
184 | arg_values // argument_values |
185 | ); |
186 | } |
187 | |
188 | void TraceEventAsyncEnd1(TraceArg category_group, |
189 | TraceArg name, |
190 | TraceIDArg id, |
191 | TraceArg arg1_name, |
192 | TraceArg arg1_val) { |
193 | const char* arg_names[] = {arg1_name}; |
194 | const char* arg_values[] = {arg1_val}; |
195 | FlutterTimelineEvent(name, // label |
196 | Dart_TimelineGetMicros(), // timestamp0 |
197 | id, // timestamp1_or_async_id |
198 | Dart_Timeline_Event_Async_End, // event type |
199 | 1, // argument_count |
200 | arg_names, // argument_names |
201 | arg_values // argument_values |
202 | ); |
203 | } |
204 | |
205 | void TraceEventInstant0(TraceArg category_group, TraceArg name) { |
206 | FlutterTimelineEvent(name, // label |
207 | Dart_TimelineGetMicros(), // timestamp0 |
208 | 0, // timestamp1_or_async_id |
209 | Dart_Timeline_Event_Instant, // event type |
210 | 0, // argument_count |
211 | nullptr, // argument_names |
212 | nullptr // argument_values |
213 | ); |
214 | } |
215 | |
216 | void TraceEventInstant1(TraceArg category_group, |
217 | TraceArg name, |
218 | TraceArg arg1_name, |
219 | TraceArg arg1_val) { |
220 | const char* arg_names[] = {arg1_name}; |
221 | const char* arg_values[] = {arg1_val}; |
222 | FlutterTimelineEvent(name, // label |
223 | Dart_TimelineGetMicros(), // timestamp0 |
224 | 0, // timestamp1_or_async_id |
225 | Dart_Timeline_Event_Instant, // event type |
226 | 1, // argument_count |
227 | arg_names, // argument_names |
228 | arg_values // argument_values |
229 | ); |
230 | } |
231 | |
232 | void TraceEventInstant2(TraceArg category_group, |
233 | TraceArg name, |
234 | TraceArg arg1_name, |
235 | TraceArg arg1_val, |
236 | TraceArg arg2_name, |
237 | TraceArg arg2_val) { |
238 | const char* arg_names[] = {arg1_name, arg2_name}; |
239 | const char* arg_values[] = {arg1_val, arg2_val}; |
240 | FlutterTimelineEvent(name, // label |
241 | Dart_TimelineGetMicros(), // timestamp0 |
242 | 0, // timestamp1_or_async_id |
243 | Dart_Timeline_Event_Instant, // event type |
244 | 2, // argument_count |
245 | arg_names, // argument_names |
246 | arg_values // argument_values |
247 | ); |
248 | } |
249 | |
250 | void TraceEventFlowBegin0(TraceArg category_group, |
251 | TraceArg name, |
252 | TraceIDArg id) { |
253 | FlutterTimelineEvent(name, // label |
254 | Dart_TimelineGetMicros(), // timestamp0 |
255 | id, // timestamp1_or_async_id |
256 | Dart_Timeline_Event_Flow_Begin, // event type |
257 | 0, // argument_count |
258 | nullptr, // argument_names |
259 | nullptr // argument_values |
260 | ); |
261 | } |
262 | |
263 | void TraceEventFlowStep0(TraceArg category_group, |
264 | TraceArg name, |
265 | TraceIDArg id) { |
266 | FlutterTimelineEvent(name, // label |
267 | Dart_TimelineGetMicros(), // timestamp0 |
268 | id, // timestamp1_or_async_id |
269 | Dart_Timeline_Event_Flow_Step, // event type |
270 | 0, // argument_count |
271 | nullptr, // argument_names |
272 | nullptr // argument_values |
273 | ); |
274 | } |
275 | |
276 | void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) { |
277 | FlutterTimelineEvent(name, // label |
278 | Dart_TimelineGetMicros(), // timestamp0 |
279 | id, // timestamp1_or_async_id |
280 | Dart_Timeline_Event_Flow_End, // event type |
281 | 0, // argument_count |
282 | nullptr, // argument_names |
283 | nullptr // argument_values |
284 | ); |
285 | } |
286 | |
287 | #else // FLUTTER_TIMELINE_ENABLED |
288 | |
289 | void TraceSetAllowlist(const std::vector<std::string>& allowlist) {} |
290 | |
291 | size_t TraceNonce() { |
292 | return 0; |
293 | } |
294 | |
295 | void TraceTimelineEvent(TraceArg category_group, |
296 | TraceArg name, |
297 | int64_t timestamp_micros, |
298 | TraceIDArg identifier, |
299 | Dart_Timeline_Event_Type type, |
300 | const std::vector<const char*>& c_names, |
301 | const std::vector<std::string>& values) {} |
302 | |
303 | void TraceTimelineEvent(TraceArg category_group, |
304 | TraceArg name, |
305 | TraceIDArg identifier, |
306 | Dart_Timeline_Event_Type type, |
307 | const std::vector<const char*>& c_names, |
308 | const std::vector<std::string>& values) {} |
309 | |
310 | void TraceEvent0(TraceArg category_group, TraceArg name) {} |
311 | |
312 | void TraceEvent1(TraceArg category_group, |
313 | TraceArg name, |
314 | TraceArg arg1_name, |
315 | TraceArg arg1_val) {} |
316 | |
317 | void TraceEvent2(TraceArg category_group, |
318 | TraceArg name, |
319 | TraceArg arg1_name, |
320 | TraceArg arg1_val, |
321 | TraceArg arg2_name, |
322 | TraceArg arg2_val) {} |
323 | |
324 | void TraceEventEnd(TraceArg name) {} |
325 | |
326 | void TraceEventAsyncComplete(TraceArg category_group, |
327 | TraceArg name, |
328 | TimePoint begin, |
329 | TimePoint end) {} |
330 | |
331 | void TraceEventAsyncBegin0(TraceArg category_group, |
332 | TraceArg name, |
333 | TraceIDArg id) {} |
334 | |
335 | void TraceEventAsyncEnd0(TraceArg category_group, |
336 | TraceArg name, |
337 | TraceIDArg id) {} |
338 | |
339 | void TraceEventAsyncBegin1(TraceArg category_group, |
340 | TraceArg name, |
341 | TraceIDArg id, |
342 | TraceArg arg1_name, |
343 | TraceArg arg1_val) {} |
344 | |
345 | void TraceEventAsyncEnd1(TraceArg category_group, |
346 | TraceArg name, |
347 | TraceIDArg id, |
348 | TraceArg arg1_name, |
349 | TraceArg arg1_val) {} |
350 | |
351 | void TraceEventInstant0(TraceArg category_group, TraceArg name) {} |
352 | |
353 | void TraceEventInstant1(TraceArg category_group, |
354 | TraceArg name, |
355 | TraceArg arg1_name, |
356 | TraceArg arg1_val) {} |
357 | |
358 | void TraceEventInstant2(TraceArg category_group, |
359 | TraceArg name, |
360 | TraceArg arg1_name, |
361 | TraceArg arg1_val, |
362 | TraceArg arg2_name, |
363 | TraceArg arg2_val) {} |
364 | |
365 | void TraceEventFlowBegin0(TraceArg category_group, |
366 | TraceArg name, |
367 | TraceIDArg id) {} |
368 | |
369 | void TraceEventFlowStep0(TraceArg category_group, |
370 | TraceArg name, |
371 | TraceIDArg id) {} |
372 | |
373 | void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) { |
374 | } |
375 | |
376 | #endif // FLUTTER_TIMELINE_ENABLED |
377 | |
378 | } // namespace tracing |
379 | } // namespace fml |
380 | |