[ VM / Service ] Made VM timeline functionality public through the service API.
Change-Id: I8228f0417047af53edc6f570940d452da3155bbd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106061
Reviewed-by: Siva Annamalai <asiva@google.com>
diff --git a/runtime/observatory/lib/src/repositories/timeline.dart b/runtime/observatory/lib/src/repositories/timeline.dart
index a954bf6..c2695ef 100644
--- a/runtime/observatory/lib/src/repositories/timeline.dart
+++ b/runtime/observatory/lib/src/repositories/timeline.dart
@@ -7,21 +7,21 @@
class TimelineRepository implements M.TimelineRepository {
Future<M.TimelineFlags> getFlags(M.VMRef ref) async {
S.VM vm = ref as S.VM;
- S.ServiceMap response = await vm.invokeRpc('_getVMTimelineFlags', {});
+ S.ServiceMap response = await vm.invokeRpc('getVMTimelineFlags', {});
return new S.TimelineFlags(response);
}
Future setRecordedStreams(M.VMRef ref, Iterable<M.TimelineStream> streams) {
S.VM vm = ref as S.VM;
assert(vm != null);
- return vm.invokeRpc('_setVMTimelineFlags', {
+ return vm.invokeRpc('setVMTimelineFlags', {
'recordedStreams': '[${streams.map((s) => s.name).join(', ')}]',
});
}
Future clear(M.VMRef ref) {
S.VM vm = ref as S.VM;
- return vm.invokeRpc('_clearVMTimeline', {});
+ return vm.invokeRpc('clearVMTimeline', {});
}
Future<Map<String, dynamic>> getIFrameParams(M.VMRef ref) async {
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 8d0c9f4..287d311 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(18));
+ expect(result['minor'], equals(19));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
index 8a60ea3..cdd9344 100644
--- a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
@@ -94,14 +94,14 @@
}
Map arguments = event['args'];
expect(arguments, new isInstanceOf<Map>());
- expect(arguments['isolateNumber'], new isInstanceOf<String>());
+ expect(arguments['isolateId'], new isInstanceOf<String>());
}
}
var tests = <VMTest>[
(VM vm) async {
- Map result = await vm.invokeRpcNoUpgrade('_getVMTimeline', {});
- expect(result['type'], equals('_Timeline'));
+ Map result = await vm.invokeRpcNoUpgrade('getVMTimeline', {});
+ expect(result['type'], equals('Timeline'));
expect(result['traceEvents'], new isInstanceOf<List>());
final int numEvents = result['traceEvents'].length;
List dartEvents = filterForDartEvents(result['traceEvents']);
@@ -121,7 +121,7 @@
int origin = timeOrigin(dartEvents);
int extent = timeDuration(dartEvents, origin);
// Query for the timeline with the time window for Dart events.
- result = await vm.invokeRpcNoUpgrade('_getVMTimeline',
+ result = await vm.invokeRpcNoUpgrade('getVMTimeline',
{'timeOriginMicros': origin, 'timeExtentMicros': extent});
// Verify that we received fewer events than before.
expect(result['traceEvents'].length, lessThan(numEvents));
diff --git a/runtime/observatory/tests/service/vm_timeline_events_test.dart b/runtime/observatory/tests/service/vm_timeline_events_test.dart
index 9b2e550..9586771 100644
--- a/runtime/observatory/tests/service/vm_timeline_events_test.dart
+++ b/runtime/observatory/tests/service/vm_timeline_events_test.dart
@@ -45,7 +45,7 @@
},
(Isolate isolate) async {
// Get the flags.
- Map flags = await isolate.vm.invokeRpcNoUpgrade('_getVMTimelineFlags', {});
+ Map flags = await isolate.vm.invokeRpcNoUpgrade('getVMTimelineFlags', {});
expect(flags['type'], 'TimelineFlags');
// Confirm that 'Dart' is available.
expect(flags['availableStreams'].contains('Dart'), isTrue);
@@ -54,7 +54,7 @@
},
(Isolate isolate) async {
// Enable the Dart category.
- await isolate.vm.invokeRpcNoUpgrade('_setVMTimelineFlags', {
+ await isolate.vm.invokeRpcNoUpgrade('setVMTimelineFlags', {
"recordedStreams": ["Dart"]
});
},
diff --git a/runtime/observatory/tests/service/vm_timeline_flags_test.dart b/runtime/observatory/tests/service/vm_timeline_flags_test.dart
index 4e71d95..5f5365f 100644
--- a/runtime/observatory/tests/service/vm_timeline_flags_test.dart
+++ b/runtime/observatory/tests/service/vm_timeline_flags_test.dart
@@ -31,7 +31,7 @@
hasStoppedAtBreakpoint,
(Isolate isolate) async {
// Get the flags.
- Map flags = await isolate.vm.invokeRpcNoUpgrade('_getVMTimelineFlags', {});
+ Map flags = await isolate.vm.invokeRpcNoUpgrade('getVMTimelineFlags', {});
expect(flags['type'], 'TimelineFlags');
// Confirm that 'Dart' is available.
expect(flags['availableStreams'].contains('Dart'), isTrue);
@@ -40,21 +40,21 @@
},
(Isolate isolate) async {
// Get the timeline.
- Map result = await isolate.vm.invokeRpcNoUpgrade('_getVMTimeline', {});
- expect(result['type'], equals('_Timeline'));
+ Map result = await isolate.vm.invokeRpcNoUpgrade('getVMTimeline', {});
+ expect(result['type'], equals('Timeline'));
expect(result['traceEvents'], new isInstanceOf<List>());
// Confirm that it as no non-meta data events.
expect(filterEvents(result['traceEvents'], isNotMetaData).length, 0);
},
(Isolate isolate) async {
// Enable the Dart category.
- await isolate.vm.invokeRpcNoUpgrade('_setVMTimelineFlags', {
+ await isolate.vm.invokeRpcNoUpgrade('setVMTimelineFlags', {
"recordedStreams": ["Dart"]
});
},
(Isolate isolate) async {
// Get the flags.
- Map flags = await isolate.vm.invokeRpcNoUpgrade('_getVMTimelineFlags', {});
+ Map flags = await isolate.vm.invokeRpcNoUpgrade('getVMTimelineFlags', {});
expect(flags['type'], 'TimelineFlags');
// Confirm that only Dart is being recorded.
expect(flags['recordedStreams'].length, equals(1));
@@ -65,8 +65,8 @@
hasStoppedAtBreakpoint,
(Isolate isolate) async {
// Get the timeline.
- Map result = await isolate.vm.invokeRpcNoUpgrade('_getVMTimeline', {});
- expect(result['type'], equals('_Timeline'));
+ Map result = await isolate.vm.invokeRpcNoUpgrade('getVMTimeline', {});
+ expect(result['type'], equals('Timeline'));
expect(result['traceEvents'], new isInstanceOf<List>());
print(result['traceEvents']);
// Confirm that Dart events are added.
@@ -79,16 +79,16 @@
(Isolate isolate) async {
// Disable the Dart category.
await isolate.vm
- .invokeRpcNoUpgrade('_setVMTimelineFlags', {"recordedStreams": []});
+ .invokeRpcNoUpgrade('setVMTimelineFlags', {"recordedStreams": []});
// Grab the timeline and remember the number of Dart events.
- Map result = await isolate.vm.invokeRpcNoUpgrade('_getVMTimeline', {});
- expect(result['type'], equals('_Timeline'));
+ Map result = await isolate.vm.invokeRpcNoUpgrade('getVMTimeline', {});
+ expect(result['type'], equals('Timeline'));
expect(result['traceEvents'], new isInstanceOf<List>());
dartEventCount = filterEvents(result['traceEvents'], isDart).length;
},
(Isolate isolate) async {
// Get the flags.
- Map flags = await isolate.vm.invokeRpcNoUpgrade('_getVMTimelineFlags', {});
+ Map flags = await isolate.vm.invokeRpcNoUpgrade('getVMTimelineFlags', {});
expect(flags['type'], 'TimelineFlags');
// Confirm that 'Dart' is not being recorded.
expect(flags['recordedStreams'].length, equals(0));
@@ -97,8 +97,8 @@
hasStoppedAtBreakpoint,
(Isolate isolate) async {
// Grab the timeline and verify that we haven't added any new Dart events.
- Map result = await isolate.vm.invokeRpcNoUpgrade('_getVMTimeline', {});
- expect(result['type'], equals('_Timeline'));
+ Map result = await isolate.vm.invokeRpcNoUpgrade('getVMTimeline', {});
+ expect(result['type'], equals('Timeline'));
expect(result['traceEvents'], new isInstanceOf<List>());
expect(filterEvents(result['traceEvents'], isDart).length, dartEventCount);
// Confirm that zero non-Dart events are added.
diff --git a/runtime/observatory/tests/service/write_cpu_profile_timeline_rpc_test.dart b/runtime/observatory/tests/service/write_cpu_profile_timeline_rpc_test.dart
index ea0a6ef..fad0eda 100644
--- a/runtime/observatory/tests/service/write_cpu_profile_timeline_rpc_test.dart
+++ b/runtime/observatory/tests/service/write_cpu_profile_timeline_rpc_test.dart
@@ -27,8 +27,8 @@
print(result);
expect(result['type'], equals('Success'));
- result = await isolate.vm.invokeRpcNoUpgrade('_getVMTimeline', {});
- expect(result['type'], equals('_Timeline'));
+ result = await isolate.vm.invokeRpcNoUpgrade('getVMTimeline', {});
+ expect(result['type'], equals('Timeline'));
expect(result['traceEvents'], new isInstanceOf<List>());
var events = result['traceEvents'];
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index aeaa9d0..30cddd2 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -136,6 +136,9 @@
return "File system does not exist";
case kFileDoesNotExist:
return "File does not exist";
+ case kInvalidTimelineRequest:
+ return "The timeline related request could not be completed due to the "
+ "current configuration";
default:
return "Extension error";
}
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 98d39f3..b9fdef7 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -61,6 +61,7 @@
kServiceAlreadyRegistered = 111,
kServiceDisappeared = 112,
kExpressionCompilationError = 113,
+ kInvalidTimelineRequest = 114,
// Experimental (used in private rpcs).
kFileSystemAlreadyExists = 1001,
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index eca7158..ed4dcc2 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3656,6 +3656,18 @@
TimelineEventRecorder* timeline_recorder = Timeline::recorder();
// TODO(johnmccutchan): Return an error.
ASSERT(timeline_recorder != NULL);
+ const char* name = timeline_recorder->name();
+ if ((strcmp(name, FUCHSIA_RECORDER_NAME) == 0) ||
+ (strcmp(name, SYSTRACE_RECORDER_NAME) == 0)) {
+ js->PrintError(kInvalidTimelineRequest,
+ "A recorder of type \"%s\" is "
+ "currently in use. As a result, timeline events are handled "
+ "by the OS rather than the VM. See the VM service "
+ "documentation for more details on where timeline events "
+ "can be found for this recorder type.",
+ timeline_recorder->name());
+ return true;
+ }
int64_t time_origin_micros =
Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
int64_t time_extent_micros =
@@ -4882,7 +4894,7 @@
build_expression_evaluation_scope_params },
{ "_clearCpuProfile", ClearCpuProfile,
clear_cpu_profile_params },
- { "_clearVMTimeline", ClearVMTimeline,
+ { "clearVMTimeline", ClearVMTimeline,
clear_vm_timeline_params, },
{ "_compileExpression", CompileExpression, compile_expression_params },
{ "_enableProfiler", EnableProfiler,
@@ -4959,9 +4971,9 @@
get_vm_metric_params },
{ "_getVMMetricList", GetVMMetricList,
get_vm_metric_list_params },
- { "_getVMTimeline", GetVMTimeline,
+ { "getVMTimeline", GetVMTimeline,
get_vm_timeline_params },
- { "_getVMTimelineFlags", GetVMTimelineFlags,
+ { "getVMTimelineFlags", GetVMTimelineFlags,
get_vm_timeline_flags_params },
{ "invoke", Invoke, invoke_params },
{ "kill", Kill, kill_params },
@@ -4991,7 +5003,7 @@
set_trace_class_allocation_params },
{ "setVMName", SetVMName,
set_vm_name_params },
- { "_setVMTimelineFlags", SetVMTimelineFlags,
+ { "setVMTimelineFlags", SetVMTimelineFlags,
set_vm_timeline_flags_params },
{ "_collectAllGarbage", CollectAllGarbage,
collect_all_garbage_params },
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 9546d75..6e99782 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 18
+#define SERVICE_PROTOCOL_MINOR_VERSION 19
class Array;
class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 239c6fc..52eea6b 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.18
+# Dart VM Service Protocol 3.19
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.18_ of the Dart VM Service Protocol. This
+This document describes of _version 3.19_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -27,6 +27,7 @@
- [addBreakpoint](#addbreakpoint)
- [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
- [addBreakpointAtEntry](#addbreakpointatentry)
+ - [clearVMTimeline](#clearvmtimeline)
- [evaluate](#evaluate)
- [evaluateInFrame](#evaluateinframe)
- [getAllocationProfile](#getallocationprofile)
@@ -39,6 +40,8 @@
- [getStack](#getstack)
- [getVersion](#getversion)
- [getVM](#getvm)
+ - [getVMTimeline](#getvmtimeline)
+ - [getVMTimelineFlags](#getvmtimelineflags)
- [invoke](#invoke)
- [pause](#pause)
- [kill](#kill)
@@ -50,6 +53,7 @@
- [setLibraryDebuggable](#setlibrarydebuggable)
- [setName](#setname)
- [setVMName](#setvmname)
+ - [setVMTimelineFlags](#setvmtimelineflags)
- [streamCancel](#streamcancel)
- [streamListen](#streamlisten)
- [Public Types](#public-types)
@@ -98,6 +102,9 @@
- [Stack](#stack)
- [StepOption](#stepoption)
- [Success](#success)
+ - [Timeline](#timeline)
+ - [TimelineEvent](#timelineevent)
+ - [TimelineFlags](#timelineflags)
- [TypeArguments](#typearguments)
- [UresolvedSourceLocation](#unresolvedsourcelocation)
- [Version](#version)
@@ -203,8 +210,7 @@
111 | Service already registered | Service with such name has already been registered by this client
112 | Service disappeared | Failed to fulfill service request, likely service handler is no longer available
113 | Expression compilation error | Request to compile expression failed
-
-
+114 | Invalid timeline request | The timeline related request could not be completed due to the current configuration
## Events
@@ -479,6 +485,17 @@
Note that breakpoints are added and removed on a per-isolate basis.
+
+### clearVMTimeline
+
+```
+Success clearVMTimeline()
+```
+
+Clears all VM timeline events.
+
+See [Success](#success).
+
### invoke
```
@@ -768,6 +785,42 @@
See [VM](#vm).
+
+### getVMTimeline
+
+```
+Timeline getVMTimeline(int timeOriginMicros,
+ int timeExtentMicros)
+```
+
+The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
+events.
+
+The _timeOriginMicros_ parameter is the beginning of the time range used to filter
+timeline events.
+
+The _timeExtentMicros_ parameter specifies how large the time range used to filter
+timeline events should be.
+
+For example, given _timeOriginMicros_ and _timeExtentMicros_, only timeline events
+from the following time range will be returned: `(timeOriginMicros, timeOriginMicros + timeExtentMicros)`.
+
+If _getVMTimeline_ is invoked while the current recorder is one of Fuchsia or
+Systrace, the _114_ error code, invalid timeline request, will be returned as
+timeline events are handled by the OS in these modes.
+
+### getVMTimelineFlags
+
+```
+TimelineFlags getVMTimelineFlags()
+```
+
+The _getVMTimelineFlags_ RPC returns information about the current VM timeline configuration.
+
+To change which timeline streams are currently enabled, see [setVMTimelineFlags](#setvmtimelineflags).
+
+See [TimelineFlags](#timelineflags).
+
### pause
```
@@ -794,7 +847,6 @@
### reloadSources
-
```
ReloadReport reloadSources(string isolateId,
bool force [optional],
@@ -934,6 +986,22 @@
See [Success](#success).
+### setVMTimelineFlags
+
+```
+Success setVMTimelineFlags(string[] recordedStreams)
+```
+
+The _setVMTimelineFlags_ RPC is used to set which timeline streams are enabled.
+
+The _recordedStreams_ parameter is the list of all timeline streams which are
+to be enabled. Streams not explicitly specified will be disabled. Invalid stream
+names are ignored.
+
+To get the list of currently enabled timeline streams, see [getVMTimelineFlags](#getvmtimelineflags).
+
+See [Success](#success).
+
### streamCancel
```
@@ -2767,6 +2835,21 @@
The _Success_ type is used to indicate that an operation completed successfully.
+### Timeline
+
+```
+class Timeline extends Response {
+ // A list of timeline events.
+ TimelineEvent[] traceEvents;
+
+ // The start of the period of time in which traceEvents were collected.
+ int timeOriginMicros;
+
+ // The duration of time covered by the timeline.
+ int timeExtentMicros;
+}
+```
+
### TimelineEvent
```
@@ -2776,6 +2859,23 @@
An _TimelineEvent_ is an arbitrary map that contains a [Trace Event Format](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview) event.
+### TimelineFlags
+
+```
+class TimelineFlags extends Response {
+ // The name of the recorder currently in use. Recorder types include, but are
+ // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
+ // Set to "null" if no recorder is currently set.
+ string recorderName;
+
+ // The list of all available timeline streams.
+ string[] availableStreams;
+
+ // The list of timeline streams that are currently enabled.
+ string[] recordedStreams;
+}
+```
+
### TypeArguments
```
@@ -2922,5 +3022,6 @@
3.16 | Add 'getMemoryUsage' RPC and 'MemoryUsage' object.
3.17 | Add 'Logging' event kind and the LogRecord class.
3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
+3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 36aeb96..148ee39 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.19-dev
+# Dart VM Service Protocol 3.20-dev
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.19-dev_ of the Dart VM Service Protocol. This
+This document describes of _version 3.20-dev_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -27,6 +27,7 @@
- [addBreakpoint](#addbreakpoint)
- [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
- [addBreakpointAtEntry](#addbreakpointatentry)
+ - [clearVMTimeline](#clearvmtimeline)
- [evaluate](#evaluate)
- [evaluateInFrame](#evaluateinframe)
- [getAllocationProfile](#getallocationprofile)
@@ -39,6 +40,8 @@
- [getStack](#getstack)
- [getVersion](#getversion)
- [getVM](#getvm)
+ - [getVMTimeline](#getvmtimeline)
+ - [getVMTimelineFlags](#getvmtimelineflags)
- [invoke](#invoke)
- [pause](#pause)
- [kill](#kill)
@@ -50,6 +53,7 @@
- [setLibraryDebuggable](#setlibrarydebuggable)
- [setName](#setname)
- [setVMName](#setvmname)
+ - [setVMTimelineFlags](#setvmtimelineflags)
- [streamCancel](#streamcancel)
- [streamListen](#streamlisten)
- [Public Types](#public-types)
@@ -98,6 +102,9 @@
- [Stack](#stack)
- [StepOption](#stepoption)
- [Success](#success)
+ - [Timeline](#timeline)
+ - [TimelineEvent](#timelineevent)
+ - [TimelineFlags](#timelineflags)
- [TypeArguments](#typearguments)
- [UresolvedSourceLocation](#unresolvedsourcelocation)
- [Version](#version)
@@ -203,8 +210,7 @@
111 | Service already registered | Service with such name has already been registered by this client
112 | Service disappeared | Failed to fulfill service request, likely service handler is no longer available
113 | Expression compilation error | Request to compile expression failed
-
-
+114 | Invalid timeline request | The timeline related request could not be completed due to the current configuration
## Events
@@ -479,6 +485,17 @@
Note that breakpoints are added and removed on a per-isolate basis.
+
+### clearVMTimeline
+
+```
+Success clearVMTimeline()
+```
+
+Clears all VM timeline events.
+
+See [Success](#success).
+
### invoke
```
@@ -768,6 +785,42 @@
See [VM](#vm).
+
+### getVMTimeline
+
+```
+Timeline getVMTimeline(int timeOriginMicros,
+ int timeExtentMicros)
+```
+
+The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
+events.
+
+The _timeOriginMicros_ parameter is the beginning of the time range used to filter
+timeline events.
+
+The _timeExtentMicros_ parameter specifies how large the time range used to filter
+timeline events should be.
+
+For example, given _timeOriginMicros_ and _timeExtentMicros_, only timeline events
+from the following time range will be returned: `(timeOriginMicros, timeOriginMicros + timeExtentMicros)`.
+
+If _getVMTimeline_ is invoked while the current recorder is one of Fuchsia or
+Systrace, the _114_ error code, invalid timeline request, will be returned as
+timeline events are handled by the OS in these modes.
+
+### getVMTimelineFlags
+
+```
+TimelineFlags getVMTimelineFlags()
+```
+
+The _getVMTimelineFlags_ RPC returns information about the current VM timeline configuration.
+
+To change which timeline streams are currently enabled, see [setVMTimelineFlags](#setvmtimelineflags).
+
+See [TimelineFlags](#timelineflags).
+
### pause
```
@@ -794,7 +847,6 @@
### reloadSources
-
```
ReloadReport reloadSources(string isolateId,
bool force [optional],
@@ -934,6 +986,22 @@
See [Success](#success).
+### setVMTimelineFlags
+
+```
+Success setVMTimelineFlags(string[] recordedStreams)
+```
+
+The _setVMTimelineFlags_ RPC is used to set which timeline streams are enabled.
+
+The _recordedStreams_ parameter is the list of all timeline streams which are
+to be enabled. Streams not explicitly specified will be disabled. Invalid stream
+names are ignored.
+
+To get the list of currently enabled timeline streams, see [getVMTimelineFlags](#getvmtimelineflags).
+
+See [Success](#success).
+
### streamCancel
```
@@ -2767,6 +2835,21 @@
The _Success_ type is used to indicate that an operation completed successfully.
+### Timeline
+
+```
+class Timeline extends Response {
+ // A list of timeline events.
+ TimelineEvent[] traceEvents;
+
+ // The start of the period of time in which traceEvents were collected.
+ int timeOriginMicros;
+
+ // The duration of time covered by the timeline.
+ int timeExtentMicros;
+}
+```
+
### TimelineEvent
```
@@ -2776,6 +2859,23 @@
An _TimelineEvent_ is an arbitrary map that contains a [Trace Event Format](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview) event.
+### TimelineFlags
+
+```
+class TimelineFlags extends Response {
+ // The name of the recorder currently in use. Recorder types include, but are
+ // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
+ // Set to "null" if no recorder is currently set.
+ string recorderName;
+
+ // The list of all available timeline streams.
+ string[] availableStreams;
+
+ // The list of timeline streams that are currently enabled.
+ string[] recordedStreams;
+}
+```
+
### TypeArguments
```
@@ -2922,5 +3022,6 @@
3.16 | Add 'getMemoryUsage' RPC and 'MemoryUsage' object.
3.17 | Add 'Logging' event kind and the LogRecord class.
3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
+3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 329f488..8b9a644 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -17,6 +17,7 @@
#include "vm/lockers.h"
#include "vm/log.h"
#include "vm/object.h"
+#include "vm/service.h"
#include "vm/service_event.h"
#include "vm/thread.h"
@@ -665,7 +666,7 @@
if (isolate_id_ != ILLEGAL_PORT) {
// If we have one, append the isolate id.
stream->UncloseObject();
- stream->PrintfProperty("isolateNumber", "%" Pd64 "",
+ stream->PrintfProperty("isolateId", ISOLATE_SERVICE_ID_FORMAT_STRING,
static_cast<int64_t>(isolate_id_));
stream->CloseObject();
}
@@ -677,7 +678,7 @@
}
if (isolate_id_ != ILLEGAL_PORT) {
// If we have one, append the isolate id.
- args.AddPropertyF("isolateNumber", "%" Pd64 "",
+ args.AddPropertyF("isolateId", ISOLATE_SERVICE_ID_FORMAT_STRING,
static_cast<int64_t>(isolate_id_));
}
}
@@ -1199,7 +1200,7 @@
return;
}
JSONObject topLevel(js);
- topLevel.AddProperty("type", "_Timeline");
+ topLevel.AddProperty("type", "Timeline");
{
JSONArray events(&topLevel, "traceEvents");
PrintJSONMeta(&events);
@@ -1294,11 +1295,13 @@
return;
}
JSONObject topLevel(js);
- topLevel.AddProperty("type", "_Timeline");
+ topLevel.AddProperty("type", "Timeline");
{
JSONArray events(&topLevel, "traceEvents");
PrintJSONMeta(&events);
}
+ topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros());
+ topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros());
}
void TimelineEventCallbackRecorder::PrintTraceEvent(
@@ -1332,11 +1335,13 @@
return;
}
JSONObject topLevel(js);
- topLevel.AddProperty("type", "_Timeline");
+ topLevel.AddProperty("type", "Timeline");
{
JSONArray events(&topLevel, "traceEvents");
PrintJSONMeta(&events);
}
+ topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros());
+ topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros());
}
void TimelineEventPlatformRecorder::PrintTraceEvent(
@@ -1380,7 +1385,7 @@
return;
}
JSONObject topLevel(js);
- topLevel.AddProperty("type", "_Timeline");
+ topLevel.AddProperty("type", "Timeline");
{
JSONArray events(&topLevel, "traceEvents");
PrintJSONMeta(&events);
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 9d43824..68d85c2 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -36,6 +36,13 @@
class VirtualMemory;
class Zone;
+#define CALLBACK_RECORDER_NAME "Callback"
+#define ENDLESS_RECORDER_NAME "Endless"
+#define FUCHSIA_RECORDER_NAME "Fuchsia"
+#define RING_RECORDER_NAME "Ring"
+#define STARTUP_RECORDER_NAME "Startup"
+#define SYSTRACE_RECORDER_NAME "Systrace"
+
// (name, fuchsia_name).
#define TIMELINE_STREAM_LIST(V) \
V(API, "dart:api") \
@@ -787,7 +794,7 @@
: TimelineEventFixedBufferRecorder(capacity) {}
virtual ~TimelineEventRingRecorder() {}
- const char* name() const { return "Ring"; }
+ const char* name() const { return RING_RECORDER_NAME; }
protected:
TimelineEventBlock* GetNewBlockLocked();
@@ -801,7 +808,7 @@
: TimelineEventFixedBufferRecorder(capacity) {}
virtual ~TimelineEventStartupRecorder() {}
- const char* name() const { return "Startup"; }
+ const char* name() const { return STARTUP_RECORDER_NAME; }
protected:
TimelineEventBlock* GetNewBlockLocked();
@@ -823,7 +830,7 @@
// |event| as it may be freed as soon as this function returns.
virtual void OnEvent(TimelineEvent* event) = 0;
- const char* name() const { return "Callback"; }
+ const char* name() const { return CALLBACK_RECORDER_NAME; }
protected:
TimelineEventBlock* GetNewBlockLocked() { return NULL; }
@@ -846,7 +853,7 @@
void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
#endif
- const char* name() const { return "Endless"; }
+ const char* name() const { return ENDLESS_RECORDER_NAME; }
protected:
TimelineEvent* StartEvent();
@@ -919,7 +926,7 @@
TimelineEventFuchsiaRecorder() {}
virtual ~TimelineEventFuchsiaRecorder() {}
- const char* name() const { return "Fuchsia"; }
+ const char* name() const { return FUCHSIA_RECORDER_NAME; }
private:
void OnEvent(TimelineEvent* event);
@@ -939,7 +946,7 @@
char* buffer,
intptr_t buffer_size);
- const char* name() const { return "Systrace"; }
+ const char* name() const { return SYSTRACE_RECORDER_NAME; }
private:
void OnEvent(TimelineEvent* event);
diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc
index eaf09f6..56313ab 100644
--- a/runtime/vm/timeline_test.cc
+++ b/runtime/vm/timeline_test.cc
@@ -256,8 +256,8 @@
JSONStream js;
TimelineEventFilter filter;
recorder->PrintJSON(&js, &filter);
- // Check the type. This test will fail if we ever make Timeline public.
- EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString());
+ // Check the type.
+ EXPECT_SUBSTRING("\"type\":\"Timeline\"", js.ToCString());
// Check that there is a traceEvents array.
EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString());
}
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 4237f28..636feb9 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -69,6 +69,7 @@
const kServiceAlreadyRegistered = 111;
const kServiceDisappeared = 112;
const kExpressionCompilationError = 113;
+const kInvalidTimelineRequest = 114;
// Experimental (used in private rpcs).
const kFileSystemAlreadyExists = 1001;
@@ -87,6 +88,8 @@
kServiceAlreadyRegistered: 'Service already registered',
kServiceDisappeared: 'Service has disappeared',
kExpressionCompilationError: 'Expression compilation error',
+ kInvalidTimelineRequest: 'The timeline related request could not be completed'
+ 'due to the current configuration',
};
String encodeRpcError(Message message, int code, {String details}) {