blob: 7e11b2c6f8e888ce5d96d4522dd49d93a6152d55 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/trace_event.h"
#include <algorithm>
#include <atomic>
#include <utility>
#include "flutter/fml/ascii_trie.h"
#include "flutter/fml/build_config.h"
#include "flutter/fml/logging.h"
#if (FLUTTER_RELEASE && !defined(OS_FUCHSIA))
#define TIMELINE_ENABLED 0
#else
#define TIMELINE_ENABLED 1
#endif
namespace fml {
namespace tracing {
#if TIMELINE_ENABLED
namespace {
AsciiTrie gWhitelist;
inline void FlutterTimelineEvent(const char* label,
int64_t timestamp0,
int64_t timestamp1_or_async_id,
Dart_Timeline_Event_Type type,
intptr_t argument_count,
const char** argument_names,
const char** argument_values) {
if (gWhitelist.Query(label)) {
Dart_TimelineEvent(label, timestamp0, timestamp1_or_async_id, type,
argument_count, argument_names, argument_values);
}
}
} // namespace
void TraceSetWhitelist(const std::vector<std::string>& whitelist) {
gWhitelist.Fill(whitelist);
}
size_t TraceNonce() {
static std::atomic_size_t gLastItem;
return ++gLastItem;
}
void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
TraceIDArg identifier,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& c_names,
const std::vector<std::string>& values) {
const auto argument_count = std::min(c_names.size(), values.size());
std::vector<const char*> c_values;
c_values.resize(argument_count, nullptr);
for (size_t i = 0; i < argument_count; i++) {
c_values[i] = values[i].c_str();
}
FlutterTimelineEvent(
name, // label
Dart_TimelineGetMicros(), // timestamp0
identifier, // timestamp1_or_async_id
type, // event type
argument_count, // argument_count
const_cast<const char**>(c_names.data()), // argument_names
c_values.data() // argument_values
);
}
void TraceEvent0(TraceArg category_group, TraceArg name) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
0, // timestamp1_or_async_id
Dart_Timeline_Event_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEvent1(TraceArg category_group,
TraceArg name,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
0, // timestamp1_or_async_id
Dart_Timeline_Event_Begin, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEvent2(TraceArg category_group,
TraceArg name,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
TraceArg arg2_val) {
const char* arg_names[] = {arg1_name, arg2_name};
const char* arg_values[] = {arg1_val, arg2_val};
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
0, // timestamp1_or_async_id
Dart_Timeline_Event_Begin, // event type
2, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventEnd(TraceArg name) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
0, // timestamp1_or_async_id
Dart_Timeline_Event_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncComplete(TraceArg category_group,
TraceArg name,
TimePoint begin,
TimePoint end) {
auto identifier = TraceNonce();
if (begin > end) {
std::swap(begin, end);
}
FlutterTimelineEvent(name, // label
begin.ToEpochDelta().ToMicroseconds(), // timestamp0
identifier, // timestamp1_or_async_id
Dart_Timeline_Event_Async_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
FlutterTimelineEvent(name, // label
end.ToEpochDelta().ToMicroseconds(), // timestamp0
identifier, // timestamp1_or_async_id
Dart_Timeline_Event_Async_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Async_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncEnd0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Async_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventAsyncBegin1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Async_Begin, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventAsyncEnd1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
TraceArg arg1_name,
TraceArg arg1_val) {
const char* arg_names[] = {arg1_name};
const char* arg_values[] = {arg1_val};
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Async_End, // event type
1, // argument_count
arg_names, // argument_names
arg_values // argument_values
);
}
void TraceEventInstant0(TraceArg category_group, TraceArg name) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
0, // timestamp1_or_async_id
Dart_Timeline_Event_Instant, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventFlowBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Flow_Begin, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventFlowStep0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Flow_Step, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) {
FlutterTimelineEvent(name, // label
Dart_TimelineGetMicros(), // timestamp0
id, // timestamp1_or_async_id
Dart_Timeline_Event_Flow_End, // event type
0, // argument_count
nullptr, // argument_names
nullptr // argument_values
);
}
#else // TIMELINE_ENABLED
void TraceSetWhitelist(const std::vector<std::string>& whitelist) {}
size_t TraceNonce() {
return 0;
}
void TraceTimelineEvent(TraceArg category_group,
TraceArg name,
TraceIDArg identifier,
Dart_Timeline_Event_Type type,
const std::vector<const char*>& c_names,
const std::vector<std::string>& values) {}
void TraceEvent0(TraceArg category_group, TraceArg name) {}
void TraceEvent1(TraceArg category_group,
TraceArg name,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEvent2(TraceArg category_group,
TraceArg name,
TraceArg arg1_name,
TraceArg arg1_val,
TraceArg arg2_name,
TraceArg arg2_val) {}
void TraceEventEnd(TraceArg name) {}
void TraceEventAsyncComplete(TraceArg category_group,
TraceArg name,
TimePoint begin,
TimePoint end) {}
void TraceEventAsyncBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventAsyncEnd0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventAsyncBegin1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEventAsyncEnd1(TraceArg category_group,
TraceArg name,
TraceIDArg id,
TraceArg arg1_name,
TraceArg arg1_val) {}
void TraceEventInstant0(TraceArg category_group, TraceArg name) {}
void TraceEventFlowBegin0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventFlowStep0(TraceArg category_group,
TraceArg name,
TraceIDArg id) {}
void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) {
}
#endif // TIMELINE_ENABLED
} // namespace tracing
} // namespace fml