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
15namespace fml {
16namespace tracing {
17
18#if FLUTTER_TIMELINE_ENABLED
19
20namespace {
21AsciiTrie gAllowlist;
22
23inline 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
37void TraceSetAllowlist(const std::vector<std::string>& allowlist) {
38 gAllowlist.Fill(allowlist);
39}
40
41size_t TraceNonce() {
42 static std::atomic_size_t gLastItem;
43 return ++gLastItem;
44}
45
46void 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
73void 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
89void 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
100void 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
116void 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
134void 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
145void 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
158void 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
171void 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
188void 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
205void 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
216void 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
232void 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
250void 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
263void 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
276void 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
289void TraceSetAllowlist(const std::vector<std::string>& allowlist) {}
290
291size_t TraceNonce() {
292 return 0;
293}
294
295void 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
303void 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
310void TraceEvent0(TraceArg category_group, TraceArg name) {}
311
312void TraceEvent1(TraceArg category_group,
313 TraceArg name,
314 TraceArg arg1_name,
315 TraceArg arg1_val) {}
316
317void TraceEvent2(TraceArg category_group,
318 TraceArg name,
319 TraceArg arg1_name,
320 TraceArg arg1_val,
321 TraceArg arg2_name,
322 TraceArg arg2_val) {}
323
324void TraceEventEnd(TraceArg name) {}
325
326void TraceEventAsyncComplete(TraceArg category_group,
327 TraceArg name,
328 TimePoint begin,
329 TimePoint end) {}
330
331void TraceEventAsyncBegin0(TraceArg category_group,
332 TraceArg name,
333 TraceIDArg id) {}
334
335void TraceEventAsyncEnd0(TraceArg category_group,
336 TraceArg name,
337 TraceIDArg id) {}
338
339void TraceEventAsyncBegin1(TraceArg category_group,
340 TraceArg name,
341 TraceIDArg id,
342 TraceArg arg1_name,
343 TraceArg arg1_val) {}
344
345void TraceEventAsyncEnd1(TraceArg category_group,
346 TraceArg name,
347 TraceIDArg id,
348 TraceArg arg1_name,
349 TraceArg arg1_val) {}
350
351void TraceEventInstant0(TraceArg category_group, TraceArg name) {}
352
353void TraceEventInstant1(TraceArg category_group,
354 TraceArg name,
355 TraceArg arg1_name,
356 TraceArg arg1_val) {}
357
358void TraceEventInstant2(TraceArg category_group,
359 TraceArg name,
360 TraceArg arg1_name,
361 TraceArg arg1_val,
362 TraceArg arg2_name,
363 TraceArg arg2_val) {}
364
365void TraceEventFlowBegin0(TraceArg category_group,
366 TraceArg name,
367 TraceIDArg id) {}
368
369void TraceEventFlowStep0(TraceArg category_group,
370 TraceArg name,
371 TraceIDArg id) {}
372
373void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) {
374}
375
376#endif // FLUTTER_TIMELINE_ENABLED
377
378} // namespace tracing
379} // namespace fml
380