Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e8710ac

Browse files
authored
Handle deprecation of Dart_TimelineEvent Embedder API (#42497)
This PR changes usages of `Dart_TimelineEvent` to `Dart_RecordTimelineEvent` as `Dart_TimelineEvent` was deprecated in https://dart-review.googlesource.com/c/sdk/+/308721.
1 parent 2438ff8 commit e8710ac

18 files changed

+388
-110
lines changed

flow/frame_timings.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
#include "flutter/fml/time/time_delta.h"
1515
#include "flutter/fml/time/time_point.h"
1616

17-
#define TRACE_EVENT_WITH_FRAME_NUMBER(recorder, category_group, name) \
18-
TRACE_EVENT1(category_group, name, "frame_number", \
19-
recorder->GetFrameNumberTraceArg())
17+
#define TRACE_EVENT_WITH_FRAME_NUMBER(recorder, category_group, name, \
18+
flow_id_count, flow_ids) \
19+
TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, flow_ids, \
20+
"frame_number", \
21+
recorder->GetFrameNumberTraceArg())
2022

2123
namespace flutter {
2224

fml/trace_event.cc

Lines changed: 102 additions & 24 deletions
Large diffs are not rendered by default.

fml/trace_event.h

Lines changed: 128 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,27 @@
2121
::fml::tracing::TraceCounterNopHACK((a), (b), (c), (arg1), __VA_ARGS__);
2222

2323
#define FML_TRACE_EVENT(a, b, args...) TRACE_DURATION(a, b)
24+
// On Fuchsia, the flow_id arguments to this macro are ignored.
25+
#define FML_TRACE_EVENT_WITH_FLOW_IDS(category_group, name, flow_id_count, \
26+
flow_ids, ...) \
27+
FML_TRACE_EVENT(category_group, name)
2428

2529
#define TRACE_EVENT0(a, b) TRACE_DURATION(a, b)
30+
// On Fuchsia, the flow_id arguments to this macro are ignored.
31+
#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, \
32+
flow_ids) \
33+
TRACE_EVENT0(category_group, name)
2634
#define TRACE_EVENT1(a, b, c, d) TRACE_DURATION(a, b, c, d)
35+
// On Fuchsia, the flow_id arguments to this macro are ignored.
36+
#define TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, \
37+
flow_ids, arg1_name, arg1_val) \
38+
TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
2739
#define TRACE_EVENT2(a, b, c, d, e, f) TRACE_DURATION(a, b, c, d, e, f)
2840
#define TRACE_EVENT_ASYNC_BEGIN0(a, b, c) TRACE_ASYNC_BEGIN(a, b, c)
41+
// On Fuchsia, the flow_id arguments to this macro are ignored.
42+
#define TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS(category_group, name, id, \
43+
flow_id_count, flow_ids) \
44+
TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)
2945
#define TRACE_EVENT_ASYNC_END0(a, b, c) TRACE_ASYNC_END(a, b, c)
3046
#define TRACE_EVENT_ASYNC_BEGIN1(a, b, c, d, e) TRACE_ASYNC_BEGIN(a, b, c, d, e)
3147
#define TRACE_EVENT_ASYNC_END1(a, b, c, d, e) TRACE_ASYNC_END(a, b, c, d, e)
@@ -83,49 +99,93 @@
8399
// ```
84100
//
85101
// Instead, either use different `name` or `arg1` parameter names.
86-
#define FML_TRACE_EVENT(category_group, name, ...) \
87-
::fml::tracing::TraceEvent((category_group), (name), __VA_ARGS__); \
102+
#define FML_TRACE_EVENT_WITH_FLOW_IDS(category_group, name, flow_id_count, \
103+
flow_ids, ...) \
104+
::fml::tracing::TraceEvent((category_group), (name), (flow_id_count), \
105+
(flow_ids), __VA_ARGS__); \
88106
__FML__AUTO_TRACE_END(name)
89107

90-
#define TRACE_EVENT0(category_group, name) \
91-
::fml::tracing::TraceEvent0(category_group, name); \
108+
// Avoid using the same `name` and `argX_name` for nested traces, which can
109+
// lead to double free errors. E.g. the following code should be avoided:
110+
//
111+
// ```cpp
112+
// {
113+
// TRACE_EVENT1("flutter", "Foo::Bar", "count", "initial_count_value");
114+
// ...
115+
// TRACE_EVENT_INSTANT1("flutter", "Foo::Bar",
116+
// "count", "updated_count_value");
117+
// }
118+
// ```
119+
//
120+
// Instead, either use different `name` or `arg1` parameter names.
121+
#define FML_TRACE_EVENT(category_group, name, ...) \
122+
FML_TRACE_EVENT_WITH_FLOW_IDS((category_group), (name), \
123+
/*flow_id_count=*/(0), /*flow_ids=*/(nullptr), \
124+
__VA_ARGS__)
125+
126+
#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, \
127+
flow_ids) \
128+
::fml::tracing::TraceEvent0(category_group, name, flow_id_count, flow_ids); \
92129
__FML__AUTO_TRACE_END(name)
93130

94-
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
95-
::fml::tracing::TraceEvent1(category_group, name, arg1_name, arg1_val); \
131+
#define TRACE_EVENT0(category_group, name) \
132+
TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, /*flow_id_count=*/0, \
133+
/*flow_ids=*/nullptr)
134+
135+
#define TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, \
136+
flow_ids, arg1_name, arg1_val) \
137+
::fml::tracing::TraceEvent1(category_group, name, flow_id_count, flow_ids, \
138+
arg1_name, arg1_val); \
96139
__FML__AUTO_TRACE_END(name)
97140

141+
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
142+
TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, /*flow_id_count=*/0, \
143+
/*flow_ids=*/nullptr, arg1_name, arg1_val)
144+
98145
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
99146
arg2_val) \
100-
::fml::tracing::TraceEvent2(category_group, name, arg1_name, arg1_val, \
147+
::fml::tracing::TraceEvent2(category_group, name, /*flow_id_count=*/0, \
148+
/*flow_ids=*/nullptr, arg1_name, arg1_val, \
101149
arg2_name, arg2_val); \
102150
__FML__AUTO_TRACE_END(name)
103151

152+
#define TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS(category_group, name, id, \
153+
flow_id_count, flow_ids) \
154+
::fml::tracing::TraceEventAsyncBegin0(category_group, name, id, \
155+
flow_id_count, flow_ids);
156+
104157
#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \
105-
::fml::tracing::TraceEventAsyncBegin0(category_group, name, id);
158+
TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS( \
159+
category_group, name, id, /*flow_id_count=*/0, /*flow_ids=*/nullptr)
106160

107161
#define TRACE_EVENT_ASYNC_END0(category_group, name, id) \
108162
::fml::tracing::TraceEventAsyncEnd0(category_group, name, id);
109163

110-
#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
111-
arg1_val) \
112-
::fml::tracing::TraceEventAsyncBegin1(category_group, name, id, arg1_name, \
113-
arg1_val);
164+
#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
165+
arg1_val) \
166+
::fml::tracing::TraceEventAsyncBegin1( \
167+
category_group, name, id, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
168+
arg1_name, arg1_val);
114169

115170
#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
116-
::fml::tracing::TraceEventAsyncEnd1(category_group, name, id, arg1_name, \
117-
arg1_val);
171+
::fml::tracing::TraceEventAsyncEnd1( \
172+
category_group, name, id, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
173+
arg1_name, arg1_val);
118174

119175
#define TRACE_EVENT_INSTANT0(category_group, name) \
120-
::fml::tracing::TraceEventInstant0(category_group, name);
176+
::fml::tracing::TraceEventInstant0( \
177+
category_group, name, /*flow_id_count=*/0, /*flow_ids=*/nullptr);
121178

122179
#define TRACE_EVENT_INSTANT1(category_group, name, arg1_name, arg1_val) \
123-
::fml::tracing::TraceEventInstant1(category_group, name, arg1_name, arg1_val);
180+
::fml::tracing::TraceEventInstant1( \
181+
category_group, name, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
182+
arg1_name, arg1_val);
124183

125184
#define TRACE_EVENT_INSTANT2(category_group, name, arg1_name, arg1_val, \
126185
arg2_name, arg2_val) \
127-
::fml::tracing::TraceEventInstant2(category_group, name, arg1_name, \
128-
arg1_val, arg2_name, arg2_val);
186+
::fml::tracing::TraceEventInstant2( \
187+
category_group, name, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
188+
arg1_name, arg1_val, arg2_name, arg2_val);
129189

130190
#define TRACE_FLOW_BEGIN(category, name, id) \
131191
::fml::tracing::TraceEventFlowBegin0(category, name, id);
@@ -157,6 +217,8 @@ void TraceSetAllowlist(const std::vector<std::string>& allowlist);
157217
typedef void (*TimelineEventHandler)(const char*,
158218
int64_t,
159219
int64_t,
220+
intptr_t,
221+
const int64_t*,
160222
Dart_Timeline_Event_Type,
161223
intptr_t,
162224
const char**,
@@ -176,13 +238,17 @@ void TraceTimelineEvent(TraceArg category_group,
176238
TraceArg name,
177239
int64_t timestamp_micros,
178240
TraceIDArg id,
241+
size_t flow_id_count,
242+
const uint64_t* flow_ids,
179243
Dart_Timeline_Event_Type type,
180244
const std::vector<const char*>& names,
181245
const std::vector<std::string>& values);
182246

183247
void TraceTimelineEvent(TraceArg category_group,
184248
TraceArg name,
185249
TraceIDArg id,
250+
size_t flow_id_count,
251+
const uint64_t* flow_ids,
186252
Dart_Timeline_Event_Type type,
187253
const std::vector<const char*>& names,
188254
const std::vector<std::string>& values);
@@ -241,7 +307,8 @@ void TraceCounter(TraceArg category,
241307
Args... args) {
242308
#if FLUTTER_TIMELINE_ENABLED
243309
auto split = SplitArguments(args...);
244-
TraceTimelineEvent(category, name, identifier, Dart_Timeline_Event_Counter,
310+
TraceTimelineEvent(category, name, identifier, /*flow_id_count=*/0,
311+
/*flow_ids=*/nullptr, Dart_Timeline_Event_Counter,
245312
split.first, split.second);
246313
#endif // FLUTTER_TIMELINE_ENABLED
247314
}
@@ -255,23 +322,34 @@ void TraceCounterNopHACK(TraceArg category,
255322
Args... args) {}
256323

257324
template <typename... Args>
258-
void TraceEvent(TraceArg category, TraceArg name, Args... args) {
325+
void TraceEvent(TraceArg category,
326+
TraceArg name,
327+
size_t flow_id_count,
328+
const uint64_t* flow_ids,
329+
Args... args) {
259330
#if FLUTTER_TIMELINE_ENABLED
260331
auto split = SplitArguments(args...);
261-
TraceTimelineEvent(category, name, 0, Dart_Timeline_Event_Begin, split.first,
262-
split.second);
332+
TraceTimelineEvent(category, name, 0, flow_id_count, flow_ids,
333+
Dart_Timeline_Event_Begin, split.first, split.second);
263334
#endif // FLUTTER_TIMELINE_ENABLED
264335
}
265336

266-
void TraceEvent0(TraceArg category_group, TraceArg name);
337+
void TraceEvent0(TraceArg category_group,
338+
TraceArg name,
339+
size_t flow_id_count,
340+
const uint64_t* flow_ids);
267341

268342
void TraceEvent1(TraceArg category_group,
269343
TraceArg name,
344+
size_t flow_id_count,
345+
const uint64_t* flow_ids,
270346
TraceArg arg1_name,
271347
TraceArg arg1_val);
272348

273349
void TraceEvent2(TraceArg category_group,
274350
TraceArg name,
351+
size_t flow_id_count,
352+
const uint64_t* flow_ids,
275353
TraceArg arg1_name,
276354
TraceArg arg1_val,
277355
TraceArg arg2_name,
@@ -300,6 +378,8 @@ void TraceEventAsyncComplete(TraceArg category_group,
300378
name, // name
301379
begin_micros, // timestamp_micros
302380
identifier, // identifier
381+
0, // flow_id_count
382+
nullptr, // flow_ids
303383
Dart_Timeline_Event_Async_Begin, // type
304384
split.first, // names
305385
split.second // values
@@ -309,6 +389,8 @@ void TraceEventAsyncComplete(TraceArg category_group,
309389
name, // name
310390
end_micros, // timestamp_micros
311391
identifier, // identifier
392+
0, // flow_id_count
393+
nullptr, // flow_ids
312394
Dart_Timeline_Event_Async_End, // type
313395
split.first, // names
314396
split.second // values
@@ -318,13 +400,17 @@ void TraceEventAsyncComplete(TraceArg category_group,
318400

319401
void TraceEventAsyncBegin0(TraceArg category_group,
320402
TraceArg name,
321-
TraceIDArg id);
403+
TraceIDArg id,
404+
size_t flow_id_count,
405+
const uint64_t* flow_ids);
322406

323407
void TraceEventAsyncEnd0(TraceArg category_group, TraceArg name, TraceIDArg id);
324408

325409
void TraceEventAsyncBegin1(TraceArg category_group,
326410
TraceArg name,
327411
TraceIDArg id,
412+
size_t flow_id_count,
413+
const uint64_t* flow_ids,
328414
TraceArg arg1_name,
329415
TraceArg arg1_val);
330416

@@ -334,15 +420,22 @@ void TraceEventAsyncEnd1(TraceArg category_group,
334420
TraceArg arg1_name,
335421
TraceArg arg1_val);
336422

337-
void TraceEventInstant0(TraceArg category_group, TraceArg name);
423+
void TraceEventInstant0(TraceArg category_group,
424+
TraceArg name,
425+
size_t flow_id_count,
426+
const uint64_t* flow_ids);
338427

339428
void TraceEventInstant1(TraceArg category_group,
340429
TraceArg name,
430+
size_t flow_id_count,
431+
const uint64_t* flow_ids,
341432
TraceArg arg1_name,
342433
TraceArg arg1_val);
343434

344435
void TraceEventInstant2(TraceArg category_group,
345436
TraceArg name,
437+
size_t flow_id_count,
438+
const uint64_t* flow_ids,
346439
TraceArg arg1_name,
347440
TraceArg arg1_val,
348441
TraceArg arg2_name,
@@ -376,7 +469,10 @@ class ScopedInstantEnd {
376469
class TraceFlow {
377470
public:
378471
explicit TraceFlow(const char* label) : label_(label), nonce_(TraceNonce()) {
472+
TraceEvent0("flutter", label_, /*flow_id_count=*/1,
473+
/*flow_ids=*/&nonce_);
379474
TraceEventFlowBegin0("flutter", label_, nonce_);
475+
TraceEventEnd(label_);
380476
}
381477

382478
~TraceFlow() { End(label_); }
@@ -386,19 +482,25 @@ class TraceFlow {
386482
}
387483

388484
void Step(const char* label = nullptr) const {
485+
TraceEvent0("flutter", label ? label : label_, /*flow_id_count=*/1,
486+
/*flow_ids=*/&nonce_);
389487
TraceEventFlowStep0("flutter", label ? label : label_, nonce_);
488+
TraceEventEnd(label ? label : label_);
390489
}
391490

392491
void End(const char* label = nullptr) {
393492
if (nonce_ != 0) {
493+
TraceEvent0("flutter", label ? label : label_, /*flow_id_count=*/1,
494+
/*flow_ids=*/&nonce_);
394495
TraceEventFlowEnd0("flutter", label ? label : label_, nonce_);
496+
TraceEventEnd(label ? label : label_);
395497
nonce_ = 0;
396498
}
397499
}
398500

399501
private:
400502
const char* label_;
401-
size_t nonce_;
503+
uint64_t nonce_;
402504

403505
FML_DISALLOW_COPY_AND_ASSIGN(TraceFlow);
404506
};

runtime/dart_vm.cc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -472,13 +472,15 @@ DartVM::DartVM(const std::shared_ptr<const DartVMData>& vm_data,
472472
// As this call is immediately after initialization of the Dart VM,
473473
// we are interested in only one timestamp.
474474
int64_t micros = Dart_TimelineGetMicros();
475-
Dart_TimelineEvent("FlutterEngineMainEnter", // label
476-
micros, // timestamp0
477-
micros, // timestamp1_or_async_id
478-
Dart_Timeline_Event_Instant, // event type
479-
0, // argument_count
480-
nullptr, // argument_names
481-
nullptr // argument_values
475+
Dart_RecordTimelineEvent("FlutterEngineMainEnter", // label
476+
micros, // timestamp0
477+
micros, // timestamp1_or_async_id
478+
0, // flow_id_count
479+
nullptr, // flow_ids
480+
Dart_Timeline_Event_Instant, // event type
481+
0, // argument_count
482+
nullptr, // argument_names
483+
nullptr // argument_values
482484
);
483485
}
484486

runtime/dart_vm_initializer.cc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,17 @@ void DartVMInitializer::Initialize(Dart_InitializeParams* params,
113113
void DartVMInitializer::Cleanup() {
114114
FML_DCHECK(gDartInitialized);
115115

116-
// Dart_TimelineEvent is unsafe during a concurrent call to Dart_Cleanup
116+
// Dart_RecordTimelineEvent is unsafe during a concurrent call to Dart_Cleanup
117117
// because Dart_Cleanup will destroy the timeline recorder. Clear the
118118
// initialized flag so that future calls to LogDartTimelineEvent will not
119-
// call Dart_TimelineEvent.
119+
// call Dart_RecordTimelineEvent.
120120
//
121121
// Note that this is inherently racy. If a thread sees that gDartInitialized
122-
// is set and proceeds to call Dart_TimelineEvent shortly before another
123-
// thread calls Dart_Cleanup, then the Dart_TimelineEvent call may crash
124-
// if Dart_Cleanup deletes the timeline before Dart_TimelineEvent completes.
125-
// In practice this is unlikely because Dart_Cleanup does significant other
126-
// work before deleting the timeline.
122+
// is set and proceeds to call Dart_RecordTimelineEvent shortly before another
123+
// thread calls Dart_Cleanup, then the Dart_RecordTimelineEvent call may crash
124+
// if Dart_Cleanup deletes the timeline before Dart_RecordTimelineEvent
125+
// completes. In practice this is unlikely because Dart_Cleanup does
126+
// significant other work before deleting the timeline.
127127
//
128128
// The engine can not safely guard Dart_Cleanup and LogDartTimelineEvent with
129129
// a lock due to the risk of deadlocks. Dart_Cleanup waits for various
@@ -142,12 +142,15 @@ void DartVMInitializer::Cleanup() {
142142
void DartVMInitializer::LogDartTimelineEvent(const char* label,
143143
int64_t timestamp0,
144144
int64_t timestamp1_or_async_id,
145+
intptr_t flow_id_count,
146+
const int64_t* flow_ids,
145147
Dart_Timeline_Event_Type type,
146148
intptr_t argument_count,
147149
const char** argument_names,
148150
const char** argument_values) {
149151
if (gDartInitialized) {
150-
Dart_TimelineEvent(label, timestamp0, timestamp1_or_async_id, type,
151-
argument_count, argument_names, argument_values);
152+
Dart_RecordTimelineEvent(label, timestamp0, timestamp1_or_async_id,
153+
flow_id_count, flow_ids, type, argument_count,
154+
argument_names, argument_values);
152155
}
153156
}

0 commit comments

Comments
 (0)