[vm] Don't pass and copy unused category string when recording timeline events.

TEST=ci
Change-Id: I53b60a977c2b33d29a0ca685120044ba208d3ae4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258321
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2022-09-08 22:02:46 +00:00 committed by Commit Bot
parent ace52d922b
commit e5fc6d652b
9 changed files with 71 additions and 221 deletions

View file

@ -36,13 +36,12 @@ DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0, 0) {
return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew);
}
DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 5) {
DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 4) {
#if defined(SUPPORT_TIMELINE)
GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(3));
GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, type, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(3));
TimelineEventRecorder* recorder = Timeline::recorder();
if (recorder == NULL) {
@ -56,57 +55,7 @@ DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 5) {
}
DartTimelineEventHelpers::ReportTaskEvent(
thread, event, id.AsInt64Value(), phase.ToCString(), category.ToCString(),
name.ToMallocCString(), args.ToMallocCString());
#endif // SUPPORT_TIMELINE
return Object::null();
}
DEFINE_NATIVE_ENTRY(Timeline_reportFlowEvent, 0, 5) {
#if defined(SUPPORT_TIMELINE)
GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, type, arguments->NativeArgAt(2));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, flow_id, arguments->NativeArgAt(3));
GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4));
TimelineEventRecorder* recorder = Timeline::recorder();
if (recorder == NULL) {
return Object::null();
}
TimelineEvent* event = Timeline::GetDartStream()->StartEvent();
if (event == NULL) {
// Stream was turned off.
return Object::null();
}
DartTimelineEventHelpers::ReportFlowEvent(
thread, event, category.ToCString(), name.ToMallocCString(),
type.AsInt64Value(), flow_id.AsInt64Value(), args.ToMallocCString());
#endif // SUPPORT_TIMELINE
return Object::null();
}
DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 0, 3) {
#if defined(SUPPORT_TIMELINE)
GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(2));
TimelineEventRecorder* recorder = Timeline::recorder();
if (recorder == NULL) {
return Object::null();
}
TimelineEvent* event = Timeline::GetDartStream()->StartEvent();
if (event == NULL) {
// Stream was turned off.
return Object::null();
}
DartTimelineEventHelpers::ReportInstantEvent(
thread, event, category.ToCString(), name.ToMallocCString(),
event, id.AsInt64Value(), type.Value(), name.ToMallocCString(),
args.ToMallocCString());
#endif // SUPPORT_TIMELINE
return Object::null();

View file

@ -155,9 +155,7 @@ namespace dart {
V(Timeline_getNextTaskId, 0) \
V(Timeline_getTraceClock, 0) \
V(Timeline_isDartStreamEnabled, 0) \
V(Timeline_reportFlowEvent, 5) \
V(Timeline_reportInstantEvent, 3) \
V(Timeline_reportTaskEvent, 5) \
V(Timeline_reportTaskEvent, 4) \
V(TypedData_Int8Array_new, 2) \
V(TypedData_Uint8Array_new, 2) \
V(TypedData_Uint8ClampedArray_new, 2) \

View file

@ -1680,81 +1680,48 @@ void TimelineEventBlock::Finish() {
#endif
}
void DartTimelineEventHelpers::ReportTaskEvent(Thread* thread,
TimelineEvent* event,
void DartTimelineEventHelpers::ReportTaskEvent(TimelineEvent* event,
int64_t id,
const char* phase,
const char* category,
intptr_t type,
char* name,
char* args) {
ASSERT(phase != NULL);
ASSERT((phase[0] == 'n') || (phase[0] == 'b') || (phase[0] == 'e') ||
(phase[0] == 'B') || (phase[0] == 'E'));
ASSERT(phase[1] == '\0');
const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
const int64_t start_cpu = OS::GetCurrentThreadCPUMicrosForTimeline();
switch (phase[0]) {
case 'n':
switch (static_cast<TimelineEvent::EventType>(type)) {
case TimelineEvent::kAsyncInstant:
event->AsyncInstant(name, id, start);
break;
case 'b':
case TimelineEvent::kAsyncBegin:
event->AsyncBegin(name, id, start);
break;
case 'e':
case TimelineEvent::kAsyncEnd:
event->AsyncEnd(name, id, start);
break;
case 'B':
case TimelineEvent::kBegin:
event->Begin(name, id, start, start_cpu);
break;
case 'E':
case TimelineEvent::kEnd:
event->End(name, id, start, start_cpu);
break;
default:
UNREACHABLE();
}
event->set_owns_label(true);
event->CompleteWithPreSerializedArgs(args);
}
void DartTimelineEventHelpers::ReportFlowEvent(Thread* thread,
TimelineEvent* event,
const char* category,
char* name,
int64_t type,
int64_t flow_id,
char* args) {
const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
TimelineEvent::EventType event_type =
static_cast<TimelineEvent::EventType>(type);
switch (event_type) {
case TimelineEvent::kFlowBegin:
event->FlowBegin(name, flow_id, start);
event->FlowBegin(name, id, start);
break;
case TimelineEvent::kFlowStep:
event->FlowStep(name, flow_id, start);
event->FlowStep(name, id, start);
break;
case TimelineEvent::kFlowEnd:
event->FlowEnd(name, flow_id, start);
event->FlowEnd(name, id, start);
break;
case TimelineEvent::kInstant:
event->Instant(name, start);
break;
default:
UNREACHABLE();
break;
}
event->set_owns_label(true);
event->CompleteWithPreSerializedArgs(args);
}
void DartTimelineEventHelpers::ReportInstantEvent(Thread* thread,
TimelineEvent* event,
const char* category,
char* name,
char* args) {
const int64_t start = OS::GetCurrentMonotonicMicrosForTimeline();
event->Instant(name, start);
event->set_owns_label(true);
event->CompleteWithPreSerializedArgs(args);
}
} // namespace dart
#endif // defined(SUPPORT_TIMELINE)

View file

@ -280,20 +280,21 @@ class TimelineEventArguments {
class TimelineEvent {
public:
// Keep in sync with StateBits below.
// Keep in sync with constants in sdk/lib/developer/timeline.dart.
enum EventType {
kNone,
kBegin,
kEnd,
kDuration,
kInstant,
kAsyncBegin,
kAsyncInstant,
kAsyncEnd,
kCounter,
kFlowBegin,
kFlowStep,
kFlowEnd,
kMetadata,
kNone = 0,
kBegin = 1,
kEnd = 2,
kDuration = 3,
kInstant = 4,
kAsyncBegin = 5,
kAsyncInstant = 6,
kAsyncEnd = 7,
kCounter = 8,
kFlowBegin = 9,
kFlowStep = 10,
kFlowEnd = 11,
kMetadata = 12,
kNumEventTypes,
};
@ -1067,27 +1068,11 @@ class TimelineEventFileRecorder : public TimelineEventPlatformRecorder {
class DartTimelineEventHelpers : public AllStatic {
public:
static void ReportTaskEvent(Thread* thread,
TimelineEvent* event,
static void ReportTaskEvent(TimelineEvent* event,
int64_t id,
const char* phase,
const char* category,
intptr_t type,
char* name,
char* args);
static void ReportFlowEvent(Thread* thread,
TimelineEvent* event,
const char* category,
char* name,
int64_t type,
int64_t flow_id,
char* args);
static void ReportInstantEvent(Thread* thread,
TimelineEvent* event,
const char* category,
char* name,
char* args);
};
} // namespace dart

View file

@ -145,25 +145,14 @@ int _getTraceClock() {
int _clockValue = 0;
@patch
void _reportFlowEvent(
String category, String name, int type, int id, String argumentsAsJson) {
// TODO.
}
@patch
void _reportInstantEvent(String category, String name, String argumentsAsJson) {
// TODO.
}
@patch
int _getNextTaskId() {
return 0;
}
@patch
void _reportTaskEvent(int taskId, String phase, String category, String name,
String argumentsAsJson) {
void _reportTaskEvent(
int taskId, int type, String name, String argumentsAsJson) {
// TODO.
}

View file

@ -68,25 +68,14 @@ int _getTraceClock() {
int _clockValue = 0;
@patch
void _reportFlowEvent(
String category, String name, int type, int id, String argumentsAsJson) {
// TODO.
}
@patch
void _reportInstantEvent(String category, String name, String argumentsAsJson) {
// TODO.
}
@patch
int _getNextTaskId() {
return 0;
}
@patch
void _reportTaskEvent(int taskId, String phase, String category, String name,
String argumentsAsJson) {
void _reportTaskEvent(
int taskId, int type, String name, String argumentsAsJson) {
// TODO.
}

View file

@ -18,15 +18,5 @@ external int _getNextTaskId();
@patch
@pragma("vm:external-name", "Timeline_reportTaskEvent")
external void _reportTaskEvent(int taskId, String phase, String category,
String name, String argumentsAsJson);
@patch
@pragma("vm:external-name", "Timeline_reportFlowEvent")
external void _reportFlowEvent(
String category, String name, int type, int id, String argumentsAsJson);
@patch
@pragma("vm:external-name", "Timeline_reportInstantEvent")
external void _reportInstantEvent(
String category, String name, String argumentsAsJson);
external void _reportTaskEvent(
int taskId, int type, String name, String argumentsAsJson);

View file

@ -52,13 +52,5 @@ int _traceClock = 0;
int _getNextTaskId() => 0;
@patch
void _reportTaskEvent(int taskId, String phase, String category, String name,
String argumentsAsJson) {}
@patch
void _reportFlowEvent(
String category, String name, int type, int id, String argumentsAsJson) {}
@patch
void _reportInstantEvent(
String category, String name, String argumentsAsJson) {}
void _reportTaskEvent(
int taskId, int type, String name, String argumentsAsJson) {}

View file

@ -16,6 +16,18 @@ typedef TimelineSyncFunction<T> = T Function();
// TODO: This typedef is not used.
typedef Future TimelineAsyncFunction();
// These values must be kept in sync with the enum "EventType" in
// runtime/vm/timeline.h.
const int _begin = 1;
const int _end = 2;
const int _instant = 4;
const int _asyncBegin = 5;
const int _asyncInstant = 6;
const int _asyncEnd = 7;
const int _flowBegin = 9;
const int _flowStep = 10;
const int _flowEnd = 11;
/// A class to represent Flow events.
///
/// [Flow] objects are used to thread flow events between timeline slices,
@ -41,12 +53,6 @@ typedef Future TimelineAsyncFunction();
/// }, flow: Flow.end(flow.id));
/// ```
class Flow {
// These values must be kept in sync with the enum "EventType" in
// runtime/vm/timeline.h.
static const int _begin = 9;
static const int _step = 10;
static const int _end = 11;
final int _type;
/// The flow id of the flow event.
@ -60,7 +66,7 @@ class Flow {
/// If [id] is not provided, an id that conflicts with no other Dart-generated
/// flow id's will be generated.
static Flow begin({int? id}) {
return new Flow._(_begin, id ?? _getNextTaskId());
return new Flow._(_flowBegin, id ?? _getNextTaskId());
}
/// A "step" Flow event.
@ -68,14 +74,14 @@ class Flow {
/// When passed to a [Timeline] method, generates a "step" Flow event.
/// The [id] argument is required. It can come either from another [Flow]
/// event, or some id that comes from the environment.
static Flow step(int id) => new Flow._(_step, id);
static Flow step(int id) => new Flow._(_flowStep, id);
/// An "end" Flow event.
///
/// When passed to a [Timeline] method, generates a "end" Flow event.
/// The [id] argument is required. It can come either from another [Flow]
/// event, or some id that comes from the environment.
static Flow end(int id) => new Flow._(_end, id);
static Flow end(int id) => new Flow._(_flowEnd, id);
}
/// Add to the timeline.
@ -145,11 +151,10 @@ class Timeline {
// Stream is disabled.
return;
}
Map? instantArguments;
if (arguments != null) {
instantArguments = new Map.from(arguments);
}
_reportInstantEvent('Dart', name, _argumentsAsJson(instantArguments));
// Instant events don't have an id because they don't need to be paired with
// other events.
int taskId = 0;
_reportTaskEvent(taskId, _instant, name, _argumentsAsJson(arguments));
}
/// A utility method to time a synchronous [function]. Internally calls
@ -258,7 +263,7 @@ class TimelineTask {
instantArguments[_kFilterKey] = _filterKey;
}
_reportTaskEvent(
_taskId, 'n', 'Dart', name, _argumentsAsJson(instantArguments));
_taskId, _asyncInstant, name, _argumentsAsJson(instantArguments));
}
/// Finish the last synchronous operation that was started.
@ -305,9 +310,6 @@ class TimelineTask {
/// An asynchronous block of time on the timeline. This block can be kept
/// open across isolate messages.
class _AsyncBlock {
/// The category this block belongs to.
final String category = 'Dart';
/// The name of this block.
final String name;
@ -318,21 +320,18 @@ class _AsyncBlock {
// Emit the start event.
void _start(Map arguments) {
_reportTaskEvent(_taskId, 'b', category, name, _argumentsAsJson(arguments));
_reportTaskEvent(_taskId, _asyncBegin, name, _argumentsAsJson(arguments));
}
// Emit the finish event.
void _finish(Map? arguments) {
_reportTaskEvent(_taskId, 'e', category, name, _argumentsAsJson(arguments));
_reportTaskEvent(_taskId, _asyncEnd, name, _argumentsAsJson(arguments));
}
}
/// A synchronous block of time on the timeline. This block should not be
/// kept open across isolate messages.
class _SyncBlock {
/// The category this block belongs to.
final String category = 'Dart';
/// The name of this block.
final String name;
@ -352,17 +351,17 @@ class _SyncBlock {
/// Start this block of time.
void _startSync() {
_reportTaskEvent(taskId, 'B', category, name, _jsonArguments);
_reportTaskEvent(taskId, _begin, name, _jsonArguments);
}
/// Finish this block of time. At this point, this block can no longer be
/// used.
void finish() {
// Report event to runtime.
_reportTaskEvent(taskId, 'E', category, name, _jsonArguments);
_reportTaskEvent(taskId, _end, name, _jsonArguments);
final Flow? tempFlow = flow;
if (tempFlow != null) {
_reportFlowEvent(category, "${tempFlow.id}", tempFlow._type, tempFlow.id,
_reportTaskEvent(tempFlow.id, tempFlow._type, "${tempFlow.id}",
_argumentsAsJson(null));
}
}
@ -388,13 +387,5 @@ external int _getNextTaskId();
external int _getTraceClock();
/// Reports an event for a task.
external void _reportTaskEvent(int taskId, String phase, String category,
String name, String argumentsAsJson);
/// Reports a flow event.
external void _reportFlowEvent(
String category, String name, int type, int id, String argumentsAsJson);
/// Reports an instant event.
external void _reportInstantEvent(
String category, String name, String argumentsAsJson);
external void _reportTaskEvent(
int taskId, int type, String name, String argumentsAsJson);