mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[ 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>
This commit is contained in:
parent
5dc14be041
commit
a75ded625e
|
@ -7,21 +7,21 @@ part of repositories;
|
|||
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 {
|
||||
|
|
|
@ -12,7 +12,7 @@ var tests = <VMTest>[
|
|||
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));
|
||||
},
|
||||
|
|
|
@ -94,14 +94,14 @@ void allEventsHaveIsolateNumber(List events) {
|
|||
}
|
||||
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 @@ var tests = <VMTest>[
|
|||
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));
|
||||
|
|
|
@ -45,7 +45,7 @@ var tests = <IsolateTest>[
|
|||
},
|
||||
(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 @@ var tests = <IsolateTest>[
|
|||
},
|
||||
(Isolate isolate) async {
|
||||
// Enable the Dart category.
|
||||
await isolate.vm.invokeRpcNoUpgrade('_setVMTimelineFlags', {
|
||||
await isolate.vm.invokeRpcNoUpgrade('setVMTimelineFlags', {
|
||||
"recordedStreams": ["Dart"]
|
||||
});
|
||||
},
|
||||
|
|
|
@ -31,7 +31,7 @@ var tests = <IsolateTest>[
|
|||
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 @@ var tests = <IsolateTest>[
|
|||
},
|
||||
(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 @@ var tests = <IsolateTest>[
|
|||
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 @@ var tests = <IsolateTest>[
|
|||
(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 @@ var tests = <IsolateTest>[
|
|||
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.
|
||||
|
|
|
@ -27,8 +27,8 @@ var tests = <IsolateTest>[
|
|||
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'];
|
||||
|
|
|
@ -136,6 +136,9 @@ static const char* GetJSONRpcErrorMessage(intptr_t code) {
|
|||
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";
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ enum JSONRpcErrorCode {
|
|||
kServiceAlreadyRegistered = 111,
|
||||
kServiceDisappeared = 112,
|
||||
kExpressionCompilationError = 113,
|
||||
kInvalidTimelineRequest = 114,
|
||||
|
||||
// Experimental (used in private rpcs).
|
||||
kFileSystemAlreadyExists = 1001,
|
||||
|
|
|
@ -3656,6 +3656,18 @@ static bool GetVMTimeline(Thread* thread, JSONStream* js) {
|
|||
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 @@ static const ServiceMethodDescriptor service_methods_[] = {
|
|||
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 @@ static const ServiceMethodDescriptor service_methods_[] = {
|
|||
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 @@ static const ServiceMethodDescriptor service_methods_[] = {
|
|||
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 },
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [addBreakpoint](#addbreakpoint)
|
||||
- [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
|
||||
- [addBreakpointAtEntry](#addbreakpointatentry)
|
||||
- [clearVMTimeline](#clearvmtimeline)
|
||||
- [evaluate](#evaluate)
|
||||
- [evaluateInFrame](#evaluateinframe)
|
||||
- [getAllocationProfile](#getallocationprofile)
|
||||
|
@ -39,6 +40,8 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [getStack](#getstack)
|
||||
- [getVersion](#getversion)
|
||||
- [getVM](#getvm)
|
||||
- [getVMTimeline](#getvmtimeline)
|
||||
- [getVMTimelineFlags](#getvmtimelineflags)
|
||||
- [invoke](#invoke)
|
||||
- [pause](#pause)
|
||||
- [kill](#kill)
|
||||
|
@ -50,6 +53,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [setLibraryDebuggable](#setlibrarydebuggable)
|
||||
- [setName](#setname)
|
||||
- [setVMName](#setvmname)
|
||||
- [setVMTimelineFlags](#setvmtimelineflags)
|
||||
- [streamCancel](#streamcancel)
|
||||
- [streamListen](#streamlisten)
|
||||
- [Public Types](#public-types)
|
||||
|
@ -98,6 +102,9 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [Stack](#stack)
|
||||
- [StepOption](#stepoption)
|
||||
- [Success](#success)
|
||||
- [Timeline](#timeline)
|
||||
- [TimelineEvent](#timelineevent)
|
||||
- [TimelineFlags](#timelineflags)
|
||||
- [TypeArguments](#typearguments)
|
||||
- [UresolvedSourceLocation](#unresolvedsourcelocation)
|
||||
- [Version](#version)
|
||||
|
@ -203,8 +210,7 @@ code | message | meaning
|
|||
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 @@ See [Breakpoint](#breakpoint).
|
|||
|
||||
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 @@ The _getVM_ RPC returns global information about a Dart virtual machine.
|
|||
|
||||
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 @@ See [Success](#success).
|
|||
|
||||
### reloadSources
|
||||
|
||||
|
||||
```
|
||||
ReloadReport reloadSources(string isolateId,
|
||||
bool force [optional],
|
||||
|
@ -934,6 +986,22 @@ The _setVMName_ RPC is used to change the debugging name for the vm.
|
|||
|
||||
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 @@ class Success extends Response {
|
|||
|
||||
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 @@ class TimelineEvent {
|
|||
|
||||
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 @@ version | comments
|
|||
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
|
||||
|
|
|
@ -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 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [addBreakpoint](#addbreakpoint)
|
||||
- [addBreakpointWithScriptUri](#addbreakpointwithscripturi)
|
||||
- [addBreakpointAtEntry](#addbreakpointatentry)
|
||||
- [clearVMTimeline](#clearvmtimeline)
|
||||
- [evaluate](#evaluate)
|
||||
- [evaluateInFrame](#evaluateinframe)
|
||||
- [getAllocationProfile](#getallocationprofile)
|
||||
|
@ -39,6 +40,8 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [getStack](#getstack)
|
||||
- [getVersion](#getversion)
|
||||
- [getVM](#getvm)
|
||||
- [getVMTimeline](#getvmtimeline)
|
||||
- [getVMTimelineFlags](#getvmtimelineflags)
|
||||
- [invoke](#invoke)
|
||||
- [pause](#pause)
|
||||
- [kill](#kill)
|
||||
|
@ -50,6 +53,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [setLibraryDebuggable](#setlibrarydebuggable)
|
||||
- [setName](#setname)
|
||||
- [setVMName](#setvmname)
|
||||
- [setVMTimelineFlags](#setvmtimelineflags)
|
||||
- [streamCancel](#streamcancel)
|
||||
- [streamListen](#streamlisten)
|
||||
- [Public Types](#public-types)
|
||||
|
@ -98,6 +102,9 @@ The Service Protocol uses [JSON-RPC 2.0][].
|
|||
- [Stack](#stack)
|
||||
- [StepOption](#stepoption)
|
||||
- [Success](#success)
|
||||
- [Timeline](#timeline)
|
||||
- [TimelineEvent](#timelineevent)
|
||||
- [TimelineFlags](#timelineflags)
|
||||
- [TypeArguments](#typearguments)
|
||||
- [UresolvedSourceLocation](#unresolvedsourcelocation)
|
||||
- [Version](#version)
|
||||
|
@ -203,8 +210,7 @@ code | message | meaning
|
|||
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 @@ See [Breakpoint](#breakpoint).
|
|||
|
||||
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 @@ The _getVM_ RPC returns global information about a Dart virtual machine.
|
|||
|
||||
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 @@ See [Success](#success).
|
|||
|
||||
### reloadSources
|
||||
|
||||
|
||||
```
|
||||
ReloadReport reloadSources(string isolateId,
|
||||
bool force [optional],
|
||||
|
@ -934,6 +986,22 @@ The _setVMName_ RPC is used to change the debugging name for the vm.
|
|||
|
||||
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 @@ class Success extends Response {
|
|||
|
||||
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 @@ class TimelineEvent {
|
|||
|
||||
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 @@ version | comments
|
|||
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
|
||||
|
|
|
@ -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 @@ void TimelineEvent::PrintJSON(JSONStream* stream) const {
|
|||
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 @@ void TimelineEvent::PrintJSON(JSONStream* stream) const {
|
|||
}
|
||||
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 @@ void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js,
|
|||
return;
|
||||
}
|
||||
JSONObject topLevel(js);
|
||||
topLevel.AddProperty("type", "_Timeline");
|
||||
topLevel.AddProperty("type", "Timeline");
|
||||
{
|
||||
JSONArray events(&topLevel, "traceEvents");
|
||||
PrintJSONMeta(&events);
|
||||
|
@ -1294,11 +1295,13 @@ void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js,
|
|||
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 @@ void TimelineEventPlatformRecorder::PrintJSON(JSONStream* js,
|
|||
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 @@ void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
|
|||
return;
|
||||
}
|
||||
JSONObject topLevel(js);
|
||||
topLevel.AddProperty("type", "_Timeline");
|
||||
topLevel.AddProperty("type", "Timeline");
|
||||
{
|
||||
JSONArray events(&topLevel, "traceEvents");
|
||||
PrintJSONMeta(&events);
|
||||
|
|
|
@ -36,6 +36,13 @@ class TimelineStream;
|
|||
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 @@ class TimelineEventRingRecorder : public TimelineEventFixedBufferRecorder {
|
|||
: 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 @@ class TimelineEventStartupRecorder : public TimelineEventFixedBufferRecorder {
|
|||
: 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 @@ class TimelineEventCallbackRecorder : public TimelineEventRecorder {
|
|||
// |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 @@ class TimelineEventEndlessRecorder : public TimelineEventRecorder {
|
|||
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 @@ class TimelineEventFuchsiaRecorder : public TimelineEventPlatformRecorder {
|
|||
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 @@ class TimelineEventSystraceRecorder : public TimelineEventPlatformRecorder {
|
|||
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);
|
||||
|
|
|
@ -256,8 +256,8 @@ TEST_CASE(TimelineEventBufferPrintJSON) {
|
|||
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());
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ const kIsolateMustHaveReloaded = 110;
|
|||
const kServiceAlreadyRegistered = 111;
|
||||
const kServiceDisappeared = 112;
|
||||
const kExpressionCompilationError = 113;
|
||||
const kInvalidTimelineRequest = 114;
|
||||
|
||||
// Experimental (used in private rpcs).
|
||||
const kFileSystemAlreadyExists = 1001;
|
||||
|
@ -87,6 +88,8 @@ var _errorMessages = {
|
|||
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}) {
|
||||
|
|
Loading…
Reference in a new issue