Skip to content

Commit 6af2186

Browse files
bkonyicommit-bot@chromium.org
authored andcommitted
[ VM / Service ] Add getInstances and InstanceSet to the service protocol.
Change-Id: Ia5aab0f1bbdb99a7690a107eeef08de6a1f33656 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106561 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
1 parent 4403c58 commit 6af2186

9 files changed

Lines changed: 124 additions & 47 deletions

File tree

runtime/observatory/lib/src/elements/strongly_reachable_instances.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class StronglyReachableInstancesElement extends CustomElement
9292
if (_result == null) {
9393
return [new SpanElement()..text = 'Loading...'];
9494
}
95-
final content = _result.samples
95+
final content = _result.instances
9696
.map<Element>((sample) => new DivElement()
9797
..children = <Element>[
9898
anyRef(_isolate, sample, _objects, queue: _r.queue)
@@ -106,7 +106,7 @@ class StronglyReachableInstancesElement extends CustomElement
106106
}
107107

108108
List<Element> _createShowMoreButton() {
109-
final samples = _result.samples.toList();
109+
final samples = _result.instances.toList();
110110
if (samples.length == _result.count) {
111111
return [];
112112
}

runtime/observatory/lib/src/models/objects/class.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ abstract class Class extends Object implements ClassRef {
6969

7070
abstract class InstanceSet {
7171
int get count;
72-
Iterable<ObjectRef> get samples;
72+
Iterable<ObjectRef> get instances;
7373
}
7474

7575
abstract class TopRetainedInstances {}

runtime/observatory/lib/src/service/object.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,7 +1904,7 @@ class Isolate extends ServiceObjectOwner implements M.Isolate {
19041904
'classId': cls.id,
19051905
'limit': limit.toString(),
19061906
};
1907-
return invokeRpc('_getInstances', params);
1907+
return invokeRpc('getInstances', params);
19081908
}
19091909

19101910
Future<ServiceObject /*HeapObject*/ > getObjectByAddress(String address,
@@ -4049,7 +4049,7 @@ class TypeArguments extends HeapObject implements M.TypeArguments {
40494049
class InstanceSet extends HeapObject implements M.InstanceSet {
40504050
HeapObject dartOwner;
40514051
int count;
4052-
Iterable<HeapObject> samples;
4052+
Iterable<HeapObject> instances;
40534053

40544054
InstanceSet._empty(ServiceObjectOwner owner) : super._empty(owner);
40554055

@@ -4061,7 +4061,7 @@ class InstanceSet extends HeapObject implements M.InstanceSet {
40614061
return;
40624062
}
40634063
count = map['totalCount'];
4064-
samples = new List<HeapObject>.from(map['samples']);
4064+
instances = new List<HeapObject>.from(map['instances']);
40654065
}
40664066
}
40674067

runtime/observatory/tests/service/get_instances_rpc_test.dart

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,38 @@ var tests = <IsolateTest>[
3131
(Isolate isolate) async {
3232
var obj = await eval(isolate, 'global');
3333
var params = {
34-
'classId': obj['class']['id'],
34+
'objectId': obj['class']['id'],
3535
'limit': 4,
3636
};
37-
var result = await isolate.invokeRpcNoUpgrade('_getInstances', params);
37+
var result = await isolate.invokeRpcNoUpgrade('getInstances', params);
3838
expect(result['type'], equals('InstanceSet'));
3939
expect(result['totalCount'], equals(2));
40-
expect(result['samples'].length, equals(2));
41-
expect(result['samples'][0]['type'], equals('@Instance'));
40+
expect(result['instances'].length, equals(2));
41+
expect(result['instances'][0]['type'], equals('@Instance'));
4242

4343
// Limit is respected.
4444
params = {
45-
'classId': obj['class']['id'],
45+
'objectId': obj['class']['id'],
4646
'limit': 1,
4747
};
48-
result = await isolate.invokeRpcNoUpgrade('_getInstances', params);
48+
result = await isolate.invokeRpcNoUpgrade('getInstances', params);
4949
expect(result['type'], equals('InstanceSet'));
5050
expect(result['totalCount'], equals(2));
51-
expect(result['samples'].length, equals(1));
52-
expect(result['samples'][0]['type'], equals('@Instance'));
51+
expect(result['instances'].length, equals(1));
52+
expect(result['instances'][0]['type'], equals('@Instance'));
53+
54+
// Try an object ID that isn't a class ID
55+
params = {
56+
'objectId': isolate.rootLibrary.id,
57+
'limit': 1,
58+
};
59+
try {
60+
await isolate.invokeRpcNoUpgrade('getInstances', params);
61+
} on ServerRpcException catch (_) {
62+
// Success.
63+
} catch (e) {
64+
fail('Failed with exception: $e');
65+
}
5366
},
5467
];
5568

runtime/observatory/tests/service/get_version_rpc_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var tests = <VMTest>[
1212
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
1313
expect(result['type'], equals('Version'));
1414
expect(result['major'], equals(3));
15-
expect(result['minor'], equals(19));
15+
expect(result['minor'], equals(20));
1616
expect(result['_privateMajor'], equals(0));
1717
expect(result['_privateMinor'], equals(0));
1818
},

runtime/vm/service.cc

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,8 +2989,10 @@ static bool EvaluateInFrame(Thread* thread, JSONStream* js) {
29892989

29902990
class GetInstancesVisitor : public ObjectGraph::Visitor {
29912991
public:
2992-
GetInstancesVisitor(const Class& cls, const Array& storage)
2993-
: cls_(cls), storage_(storage), count_(0) {}
2992+
GetInstancesVisitor(const Class& cls,
2993+
ZoneGrowableHandlePtrArray<Object>* storage,
2994+
intptr_t limit)
2995+
: cls_(cls), storage_(storage), limit_(limit), count_(0) {}
29942996

29952997
virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
29962998
RawObject* raw_obj = it->Get();
@@ -3002,8 +3004,8 @@ class GetInstancesVisitor : public ObjectGraph::Visitor {
30023004
Object& obj = thread->ObjectHandle();
30033005
obj = raw_obj;
30043006
if (obj.GetClassId() == cls_.id()) {
3005-
if (!storage_.IsNull() && count_ < storage_.Length()) {
3006-
storage_.SetAt(count_, obj);
3007+
if (count_ < limit_) {
3008+
storage_->Add(Object::Handle(raw_obj));
30073009
}
30083010
++count_;
30093011
}
@@ -3014,7 +3016,8 @@ class GetInstancesVisitor : public ObjectGraph::Visitor {
30143016

30153017
private:
30163018
const Class& cls_;
3017-
const Array& storage_;
3019+
ZoneGrowableHandlePtrArray<Object>* storage_;
3020+
const intptr_t limit_;
30183021
intptr_t count_;
30193022
};
30203023

@@ -3023,9 +3026,9 @@ static const MethodParameter* get_instances_params[] = {
30233026
};
30243027

30253028
static bool GetInstances(Thread* thread, JSONStream* js) {
3026-
const char* target_id = js->LookupParam("classId");
3027-
if (target_id == NULL) {
3028-
PrintMissingParamError(js, "classId");
3029+
const char* object_id = js->LookupParam("objectId");
3030+
if (object_id == NULL) {
3031+
PrintMissingParamError(js, "objectId");
30293032
return true;
30303033
}
30313034
const char* limit_cstr = js->LookupParam("limit");
@@ -3038,14 +3041,20 @@ static bool GetInstances(Thread* thread, JSONStream* js) {
30383041
PrintInvalidParamError(js, "limit");
30393042
return true;
30403043
}
3041-
const Object& obj = Object::Handle(LookupHeapObject(thread, target_id, NULL));
3044+
3045+
const Object& obj = Object::Handle(LookupHeapObject(thread, object_id, NULL));
30423046
if (obj.raw() == Object::sentinel().raw() || !obj.IsClass()) {
3043-
PrintInvalidParamError(js, "classId");
3047+
PrintInvalidParamError(js, "objectId");
30443048
return true;
30453049
}
30463050
const Class& cls = Class::Cast(obj);
3047-
Array& storage = Array::Handle(Array::New(limit));
3048-
GetInstancesVisitor visitor(cls, storage);
3051+
3052+
// Ensure the array and handles created below are promptly destroyed.
3053+
StackZone zone(thread);
3054+
HANDLESCOPE(thread);
3055+
3056+
ZoneGrowableHandlePtrArray<Object> storage(thread->zone(), limit);
3057+
GetInstancesVisitor visitor(cls, &storage, limit);
30493058
ObjectGraph graph(thread);
30503059
HeapIterationScope iteration_scope(Thread::Current(), true);
30513060
graph.IterateObjects(&visitor);
@@ -3054,20 +3063,11 @@ static bool GetInstances(Thread* thread, JSONStream* js) {
30543063
jsobj.AddProperty("type", "InstanceSet");
30553064
jsobj.AddProperty("totalCount", count);
30563065
{
3057-
JSONArray samples(&jsobj, "samples");
3058-
for (int i = 0; (i < storage.Length()) && (i < count); i++) {
3059-
const Object& sample = Object::Handle(storage.At(i));
3060-
samples.AddValue(sample);
3066+
JSONArray samples(&jsobj, "instances");
3067+
for (int i = 0; (i < limit) && (i < count); i++) {
3068+
samples.AddValue(storage.At(i));
30613069
}
30623070
}
3063-
3064-
// We nil out the array after generating the response to prevent
3065-
// reporting spurious references when looking for inbound references
3066-
// after looking at allInstances.
3067-
for (intptr_t i = 0; i < storage.Length(); i++) {
3068-
storage.SetAt(i, Object::null_object());
3069-
}
3070-
30713071
return true;
30723072
}
30733073

@@ -4926,7 +4926,7 @@ static const ServiceMethodDescriptor service_methods_[] = {
49264926
get_heap_map_params },
49274927
{ "_getInboundReferences", GetInboundReferences,
49284928
get_inbound_references_params },
4929-
{ "_getInstances", GetInstances,
4929+
{ "getInstances", GetInstances,
49304930
get_instances_params },
49314931
{ "getIsolate", GetIsolate,
49324932
get_isolate_params },

runtime/vm/service.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
namespace dart {
1616

1717
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
18-
#define SERVICE_PROTOCOL_MINOR_VERSION 19
18+
#define SERVICE_PROTOCOL_MINOR_VERSION 20
1919

2020
class Array;
2121
class EmbedderServiceHandler;

runtime/vm/service/service.md

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Dart VM Service Protocol 3.19
1+
# Dart VM Service Protocol 3.20
22

33
> Please post feedback to the [observatory-discuss group][discuss-list]
44
5-
This document describes of _version 3.19_ of the Dart VM Service Protocol. This
5+
This document describes of _version 3.20_ of the Dart VM Service Protocol. This
66
protocol is used to communicate with a running Dart Virtual Machine.
77

88
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -32,6 +32,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
3232
- [evaluateInFrame](#evaluateinframe)
3333
- [getAllocationProfile](#getallocationprofile)
3434
- [getFlagList](#getflaglist)
35+
- [getInstances](#getinstances)
3536
- [getIsolate](#getisolate)
3637
- [getMemoryUsage](#getmemoryusage)
3738
- [getScripts](#getscripts)
@@ -79,6 +80,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
7980
- [Frame](#frame)
8081
- [Function](#function)
8182
- [Instance](#instance)
83+
- [InstanceSet](#instanceset)
8284
- [Isolate](#isolate)
8385
- [Library](#library)
8486
- [LibraryDependency](#librarydependency)
@@ -638,6 +640,21 @@ VM along with their current values.
638640

639641
See [FlagList](#flaglist).
640642

643+
### getInstances
644+
645+
```
646+
InstanceSet getInstances(string objectId,
647+
int limit)
648+
```
649+
650+
The _getInstances_ RPC is used to retrieve a set of instances which are of a specific type.
651+
652+
_objectId_ is the ID of the `Class` to retrieve instances for. _objectId_ must be the ID of a `Class`, otherwise an error is returned.
653+
654+
_limit_ is the maximum number of instances to be returned.
655+
656+
See [InstanceSet](#instanceset).
657+
641658
### getIsolate
642659

643660
```
@@ -2293,6 +2310,20 @@ class Isolate extends Response {
22932310

22942311
An _Isolate_ object provides information about one isolate in the VM.
22952312

2313+
### InstanceSet
2314+
2315+
```
2316+
class InstanceSet extends Response {
2317+
// The number of instances of the requested type currently allocated.
2318+
int totalCount;
2319+
2320+
// An array of instances of the requested type.
2321+
@Instance[] instances;
2322+
}
2323+
```
2324+
2325+
See [getInstances](#getinstances).
2326+
22962327
### Library
22972328

22982329
```
@@ -3002,7 +3033,7 @@ class VM extends Response {
30023033

30033034
version | comments
30043035
------- | --------
3005-
1.0 | initial revision
3036+
1.0 | Initial revision
30063037
2.0 | Describe protocol version 2.0.
30073038
3.0 | Describe protocol version 3.0. Added UnresolvedSourceLocation. Added Sentinel return to getIsolate. Add AddedBreakpointWithScriptUri. Removed Isolate.entry. The type of VM.pid was changed from string to int. Added VMUpdate events. Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
30083039
3.1 | Add the getSourceReport RPC. The getObject RPC now accepts offset and count for string objects. String objects now contain length, offset, and count properties.
@@ -3024,5 +3055,6 @@ version | comments
30243055
3.17 | Add 'Logging' event kind and the LogRecord class.
30253056
3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
30263057
3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
3058+
3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
30273059

30283060
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss

runtime/vm/service/service_dev.md

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Dart VM Service Protocol 3.20-dev
1+
# Dart VM Service Protocol 3.21-dev
22

33
> Please post feedback to the [observatory-discuss group][discuss-list]
44
5-
This document describes of _version 3.20-dev_ of the Dart VM Service Protocol. This
5+
This document describes of _version 3.21-dev_ of the Dart VM Service Protocol. This
66
protocol is used to communicate with a running Dart Virtual Machine.
77

88
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -32,6 +32,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
3232
- [evaluateInFrame](#evaluateinframe)
3333
- [getAllocationProfile](#getallocationprofile)
3434
- [getFlagList](#getflaglist)
35+
- [getInstances](#getinstances)
3536
- [getIsolate](#getisolate)
3637
- [getMemoryUsage](#getmemoryusage)
3738
- [getScripts](#getscripts)
@@ -79,6 +80,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
7980
- [Frame](#frame)
8081
- [Function](#function)
8182
- [Instance](#instance)
83+
- [InstanceSet](#instanceset)
8284
- [Isolate](#isolate)
8385
- [Library](#library)
8486
- [LibraryDependency](#librarydependency)
@@ -638,6 +640,21 @@ VM along with their current values.
638640

639641
See [FlagList](#flaglist).
640642

643+
### getInstances
644+
645+
```
646+
InstanceSet getInstances(string objectId,
647+
int limit)
648+
```
649+
650+
The _getInstances_ RPC is used to retrieve a set of instances which are of a specific type.
651+
652+
_objectId_ is the ID of the `Class` to retrieve instances for. _objectId_ must be the ID of a `Class`, otherwise an error is returned.
653+
654+
_limit_ is the maximum number of instances to be returned.
655+
656+
See [InstanceSet](#instanceset).
657+
641658
### getIsolate
642659

643660
```
@@ -2293,6 +2310,20 @@ class Isolate extends Response {
22932310

22942311
An _Isolate_ object provides information about one isolate in the VM.
22952312

2313+
### InstanceSet
2314+
2315+
```
2316+
class InstanceSet extends Response {
2317+
// The number of instances of the requested type currently allocated.
2318+
int totalCount;
2319+
2320+
// An array of instances of the requested type.
2321+
@Instance[] instances;
2322+
}
2323+
```
2324+
2325+
See [getInstances](#getinstances).
2326+
22962327
### Library
22972328

22982329
```
@@ -3002,7 +3033,7 @@ class VM extends Response {
30023033

30033034
version | comments
30043035
------- | --------
3005-
1.0 | initial revision
3036+
1.0 | Initial revision
30063037
2.0 | Describe protocol version 2.0.
30073038
3.0 | Describe protocol version 3.0. Added UnresolvedSourceLocation. Added Sentinel return to getIsolate. Add AddedBreakpointWithScriptUri. Removed Isolate.entry. The type of VM.pid was changed from string to int. Added VMUpdate events. Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
30083039
3.1 | Add the getSourceReport RPC. The getObject RPC now accepts offset and count for string objects. String objects now contain length, offset, and count properties.
@@ -3024,5 +3055,6 @@ version | comments
30243055
3.17 | Add 'Logging' event kind and the LogRecord class.
30253056
3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
30263057
3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
3058+
3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
30273059

30283060
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss

0 commit comments

Comments
 (0)