Skip to content

Commit

Permalink
Handle deprecation of Dart_TimelineEvent Embedder API
Browse files Browse the repository at this point in the history
This PR changes usages of Dart_TimelineEvent to Dart_RecordTimelineEvent as Dart_TimelineEvent was deprecated in https://dart-review.googlesource.com/c/sdk/+/308721
  • Loading branch information
derekxu16 committed Jun 20, 2023
1 parent 23a2c24 commit 3505e9e
Show file tree
Hide file tree
Showing 17 changed files with 385 additions and 108 deletions.
8 changes: 5 additions & 3 deletions flow/frame_timings.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"

#define TRACE_EVENT_WITH_FRAME_NUMBER(recorder, category_group, name) \
TRACE_EVENT1(category_group, name, "frame_number", \
recorder->GetFrameNumberTraceArg())
#define TRACE_EVENT_WITH_FRAME_NUMBER(recorder, category_group, name, \
flow_id_count, flow_ids) \
TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, flow_ids, \
"frame_number", \
recorder->GetFrameNumberTraceArg())

namespace flutter {

Expand Down
126 changes: 102 additions & 24 deletions fml/trace_event.cc

Large diffs are not rendered by default.

154 changes: 128 additions & 26 deletions fml/trace_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,27 @@
::fml::tracing::TraceCounterNopHACK((a), (b), (c), (arg1), __VA_ARGS__);

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

#define TRACE_EVENT0(a, b) TRACE_DURATION(a, b)
// On Fuchsia, the flow_id arguments to this macro are ignored.
#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, \
flow_ids) \
TRACE_EVENT0(category_group, name)
#define TRACE_EVENT1(a, b, c, d) TRACE_DURATION(a, b, c, d)
// On Fuchsia, the flow_id arguments to this macro are ignored.
#define TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, \
flow_ids, arg1_name, arg1_val) \
TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define TRACE_EVENT2(a, b, c, d, e, f) TRACE_DURATION(a, b, c, d, e, f)
#define TRACE_EVENT_ASYNC_BEGIN0(a, b, c) TRACE_ASYNC_BEGIN(a, b, c)
// On Fuchsia, the flow_id arguments to this macro are ignored.
#define TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS(category_group, name, id, \
flow_id_count, flow_ids) \
TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)
#define TRACE_EVENT_ASYNC_END0(a, b, c) TRACE_ASYNC_END(a, b, c)
#define TRACE_EVENT_ASYNC_BEGIN1(a, b, c, d, e) TRACE_ASYNC_BEGIN(a, b, c, d, e)
#define TRACE_EVENT_ASYNC_END1(a, b, c, d, e) TRACE_ASYNC_END(a, b, c, d, e)
Expand Down Expand Up @@ -83,49 +99,93 @@
// ```
//
// Instead, either use different `name` or `arg1` parameter names.
#define FML_TRACE_EVENT(category_group, name, ...) \
::fml::tracing::TraceEvent((category_group), (name), __VA_ARGS__); \
#define FML_TRACE_EVENT_WITH_FLOW_IDS(category_group, name, flow_id_count, \
flow_ids, ...) \
::fml::tracing::TraceEvent((category_group), (name), (flow_id_count), \
(flow_ids), __VA_ARGS__); \
__FML__AUTO_TRACE_END(name)

#define TRACE_EVENT0(category_group, name) \
::fml::tracing::TraceEvent0(category_group, name); \
// Avoid using the same `name` and `argX_name` for nested traces, which can
// lead to double free errors. E.g. the following code should be avoided:
//
// ```cpp
// {
// TRACE_EVENT1("flutter", "Foo::Bar", "count", "initial_count_value");
// ...
// TRACE_EVENT_INSTANT1("flutter", "Foo::Bar",
// "count", "updated_count_value");
// }
// ```
//
// Instead, either use different `name` or `arg1` parameter names.
#define FML_TRACE_EVENT(category_group, name, ...) \
FML_TRACE_EVENT_WITH_FLOW_IDS((category_group), (name), \
/*flow_id_count=*/(0), /*flow_ids=*/(nullptr), \
__VA_ARGS__)

#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, \
flow_ids) \
::fml::tracing::TraceEvent0(category_group, name, flow_id_count, flow_ids); \
__FML__AUTO_TRACE_END(name)

#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
::fml::tracing::TraceEvent1(category_group, name, arg1_name, arg1_val); \
#define TRACE_EVENT0(category_group, name) \
TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, /*flow_id_count=*/0, \
/*flow_ids=*/nullptr)

#define TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, \
flow_ids, arg1_name, arg1_val) \
::fml::tracing::TraceEvent1(category_group, name, flow_id_count, flow_ids, \
arg1_name, arg1_val); \
__FML__AUTO_TRACE_END(name)

#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, /*flow_id_count=*/0, \
/*flow_ids=*/nullptr, arg1_name, arg1_val)

#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
arg2_val) \
::fml::tracing::TraceEvent2(category_group, name, arg1_name, arg1_val, \
::fml::tracing::TraceEvent2(category_group, name, /*flow_id_count=*/0, \
/*flow_ids=*/nullptr, arg1_name, arg1_val, \
arg2_name, arg2_val); \
__FML__AUTO_TRACE_END(name)

#define TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS(category_group, name, id, \
flow_id_count, flow_ids) \
::fml::tracing::TraceEventAsyncBegin0(category_group, name, id, \
flow_id_count, flow_ids);

#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \
::fml::tracing::TraceEventAsyncBegin0(category_group, name, id);
TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS( \
category_group, name, id, /*flow_id_count=*/0, /*flow_ids=*/nullptr)

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

#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
arg1_val) \
::fml::tracing::TraceEventAsyncBegin1(category_group, name, id, arg1_name, \
arg1_val);
#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
arg1_val) \
::fml::tracing::TraceEventAsyncBegin1( \
category_group, name, id, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
arg1_name, arg1_val);

#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
::fml::tracing::TraceEventAsyncEnd1(category_group, name, id, arg1_name, \
arg1_val);
::fml::tracing::TraceEventAsyncEnd1( \
category_group, name, id, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
arg1_name, arg1_val);

#define TRACE_EVENT_INSTANT0(category_group, name) \
::fml::tracing::TraceEventInstant0(category_group, name);
::fml::tracing::TraceEventInstant0( \
category_group, name, /*flow_id_count=*/0, /*flow_ids=*/nullptr);

#define TRACE_EVENT_INSTANT1(category_group, name, arg1_name, arg1_val) \
::fml::tracing::TraceEventInstant1(category_group, name, arg1_name, arg1_val);
::fml::tracing::TraceEventInstant1( \
category_group, name, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
arg1_name, arg1_val);

#define TRACE_EVENT_INSTANT2(category_group, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
::fml::tracing::TraceEventInstant2(category_group, name, arg1_name, \
arg1_val, arg2_name, arg2_val);
::fml::tracing::TraceEventInstant2( \
category_group, name, /*flow_id_count=*/0, /*flow_ids=*/nullptr, \
arg1_name, arg1_val, arg2_name, arg2_val);

#define TRACE_FLOW_BEGIN(category, name, id) \
::fml::tracing::TraceEventFlowBegin0(category, name, id);
Expand Down Expand Up @@ -157,6 +217,8 @@ void TraceSetAllowlist(const std::vector<std::string>& allowlist);
typedef void (*TimelineEventHandler)(const char*,
int64_t,
int64_t,
intptr_t,
const int64_t*,
Dart_Timeline_Event_Type,
intptr_t,
const char**,
Expand All @@ -176,13 +238,17 @@ void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
int64_t timestamp_micros,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& names,
const std::vector<std::string>& values);

void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& names,
const std::vector<std::string>& values);
Expand Down Expand Up @@ -241,7 +307,8 @@ void TraceCounter(TraceArg category,
Args... args) {
#if FLUTTER_TIMELINE_ENABLED
auto split = SplitArguments(args...);
TraceTimelineEvent(category, name, identifier, Dart_Timeline_Event_Counter,
TraceTimelineEvent(category, name, identifier, /*flow_id_count=*/0,
/*flow_ids=*/nullptr, Dart_Timeline_Event_Counter,
split.first, split.second);
#endif // FLUTTER_TIMELINE_ENABLED
}
Expand All @@ -255,23 +322,34 @@ void TraceCounterNopHACK(TraceArg category,
Args... args) {}

template <typename... Args>
void TraceEvent(TraceArg category, TraceArg name, Args... args) {
void TraceEvent(TraceArg category,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
Args... args) {
#if FLUTTER_TIMELINE_ENABLED
auto split = SplitArguments(args...);
TraceTimelineEvent(category, name, 0, Dart_Timeline_Event_Begin, split.first,
split.second);
TraceTimelineEvent(category, name, 0, flow_id_count, flow_ids,
Dart_Timeline_Event_Begin, split.first, split.second);
#endif // FLUTTER_TIMELINE_ENABLED
}

void TraceEvent0(TraceArg category_group, TraceArg name);
void TraceEvent0(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids);

void TraceEvent1(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val);

void TraceEvent2(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
Expand Down Expand Up @@ -300,6 +378,8 @@ void TraceEventAsyncComplete(TraceArg category_group,
name, // name
begin_micros, // timestamp_micros
identifier, // identifier
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Async_Begin, // type
split.first, // names
split.second // values
Expand All @@ -309,6 +389,8 @@ void TraceEventAsyncComplete(TraceArg category_group,
name, // name
end_micros, // timestamp_micros
identifier, // identifier
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Async_End, // type
split.first, // names
split.second // values
Expand All @@ -318,13 +400,17 @@ void TraceEventAsyncComplete(TraceArg category_group,

void TraceEventAsyncBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id);
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids);

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

void TraceEventAsyncBegin1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val);

Expand All @@ -334,15 +420,22 @@ void TraceEventAsyncEnd1(TraceArg category_group,
TraceArg arg1_name,
TraceArg arg1_val);

void TraceEventInstant0(TraceArg category_group, TraceArg name);
void TraceEventInstant0(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids);

void TraceEventInstant1(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val);

void TraceEventInstant2(TraceArg category_group,
TraceArg name,
size_t flow_id_count,
const uint64_t* flow_ids,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
Expand Down Expand Up @@ -376,7 +469,10 @@ class ScopedInstantEnd {
class TraceFlow {
public:
explicit TraceFlow(const char* label) : label_(label), nonce_(TraceNonce()) {
TraceEvent0("flutter", label_, /*flow_id_count=*/1,
/*flow_ids=*/&nonce_);
TraceEventFlowBegin0("flutter", label_, nonce_);
TraceEventEnd(label_);
}

~TraceFlow() { End(label_); }
Expand All @@ -386,19 +482,25 @@ class TraceFlow {
}

void Step(const char* label = nullptr) const {
TraceEvent0("flutter", label ? label : label_, /*flow_id_count=*/1,
/*flow_ids=*/&nonce_);
TraceEventFlowStep0("flutter", label ? label : label_, nonce_);
TraceEventEnd(label ? label : label_);
}

void End(const char* label = nullptr) {
if (nonce_ != 0) {
TraceEvent0("flutter", label ? label : label_, /*flow_id_count=*/1,
/*flow_ids=*/&nonce_);
TraceEventFlowEnd0("flutter", label ? label : label_, nonce_);
TraceEventEnd(label ? label : label_);
nonce_ = 0;
}
}

private:
const char* label_;
size_t nonce_;
uint64_t nonce_;

FML_DISALLOW_COPY_AND_ASSIGN(TraceFlow);
};
Expand Down
16 changes: 9 additions & 7 deletions runtime/dart_vm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -472,13 +472,15 @@ DartVM::DartVM(const std::shared_ptr<const DartVMData>& vm_data,
// As this call is immediately after initialization of the Dart VM,
// we are interested in only one timestamp.
int64_t micros = Dart_TimelineGetMicros();
Dart_TimelineEvent("FlutterEngineMainEnter", // label
micros, // timestamp0
micros, // timestamp1_or_async_id
Dart_Timeline_Event_Instant, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
Dart_RecordTimelineEvent("FlutterEngineMainEnter", // label
micros, // timestamp0
micros, // timestamp1_or_async_id
0, // flow_id_count
nullptr, // flow_ids
Dart_Timeline_Event_Instant, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}

Expand Down
21 changes: 12 additions & 9 deletions runtime/dart_vm_initializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,17 @@ void DartVMInitializer::Initialize(Dart_InitializeParams* params,
void DartVMInitializer::Cleanup() {
FML_DCHECK(gDartInitialized);

// Dart_TimelineEvent is unsafe during a concurrent call to Dart_Cleanup
// Dart_RecordTimelineEvent is unsafe during a concurrent call to Dart_Cleanup
// because Dart_Cleanup will destroy the timeline recorder. Clear the
// initialized flag so that future calls to LogDartTimelineEvent will not
// call Dart_TimelineEvent.
// call Dart_RecordTimelineEvent.
//
// Note that this is inherently racy. If a thread sees that gDartInitialized
// is set and proceeds to call Dart_TimelineEvent shortly before another
// thread calls Dart_Cleanup, then the Dart_TimelineEvent call may crash
// if Dart_Cleanup deletes the timeline before Dart_TimelineEvent completes.
// In practice this is unlikely because Dart_Cleanup does significant other
// work before deleting the timeline.
// is set and proceeds to call Dart_RecordTimelineEvent shortly before another
// thread calls Dart_Cleanup, then the Dart_RecordTimelineEvent call may crash
// if Dart_Cleanup deletes the timeline before Dart_RecordTimelineEvent
// completes. In practice this is unlikely because Dart_Cleanup does
// significant other work before deleting the timeline.
//
// The engine can not safely guard Dart_Cleanup and LogDartTimelineEvent with
// a lock due to the risk of deadlocks. Dart_Cleanup waits for various
Expand All @@ -142,12 +142,15 @@ void DartVMInitializer::Cleanup() {
void DartVMInitializer::LogDartTimelineEvent(const char* label,
int64_t timestamp0,
int64_t timestamp1_or_async_id,
intptr_t flow_id_count,
const int64_t* flow_ids,
Dart_Timeline_Event_Type type,
intptr_t argument_count,
const char** argument_names,
const char** argument_values) {
if (gDartInitialized) {
Dart_TimelineEvent(label, timestamp0, timestamp1_or_async_id, type,
argument_count, argument_names, argument_values);
Dart_RecordTimelineEvent(label, timestamp0, timestamp1_or_async_id,
flow_id_count, flow_ids, type, argument_count,
argument_names, argument_values);
}
}
Loading

0 comments on commit 3505e9e

Please sign in to comment.