Skip to content

Commit

Permalink
Reland "[vm/service] Introduce IsolateGroup entity to vm service api.""
Browse files Browse the repository at this point in the history
This reverts commit f020ce5 with patchset 1 having original revert, rest - fixes
for calling destructors on unlinked IntrusiveDL elements and for assuming int is int64(which breaks down on simarm, ia32 bots).

Fixes #38926

Issue #36097

Change-Id: I867526c7de3786806670d1f43dbff07228f80028
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121870
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
  • Loading branch information
aam authored and commit-bot@chromium.org committed Oct 17, 2019
1 parent 8e7fa2a commit 9e636b5
Show file tree
Hide file tree
Showing 29 changed files with 937 additions and 48 deletions.
28 changes: 28 additions & 0 deletions pkg/vm_service/example/vm_service_assert.dart
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,33 @@ vms.Isolate assertIsolate(vms.Isolate obj) {
return obj;
}

vms.IsolateGroupRef assertIsolateGroupRef(vms.IsolateGroupRef obj) {
assertNotNull(obj);
assertString(obj.type);
assertString(obj.id);
assertString(obj.number);
assertString(obj.name);
return obj;
}

List<vms.IsolateGroupRef> assertListOfIsolateGroupRef(
List<vms.IsolateGroupRef> list) {
for (vms.IsolateGroupRef elem in list) {
assertIsolateGroupRef(elem);
}
return list;
}

vms.IsolateGroup assertIsolateGroup(vms.IsolateGroup obj) {
assertNotNull(obj);
assertString(obj.type);
assertString(obj.id);
assertString(obj.number);
assertString(obj.name);
assertListOfIsolateRef(obj.isolates);
return obj;
}

vms.InboundReferences assertInboundReferences(vms.InboundReferences obj) {
assertNotNull(obj);
assertString(obj.type);
Expand Down Expand Up @@ -1108,5 +1135,6 @@ vms.VM assertVM(vms.VM obj) {
assertInt(obj.pid);
assertInt(obj.startTime);
assertListOfIsolateRef(obj.isolates);
assertListOfIsolateGroupRef(obj.isolateGroups);
return obj;
}
4 changes: 4 additions & 0 deletions pkg/vm_service/java/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ src/org/dartlang/vm/service/consumer/EvaluateInFrameConsumer.java
src/org/dartlang/vm/service/consumer/FlagListConsumer.java
src/org/dartlang/vm/service/consumer/GetInboundReferencesConsumer.java
src/org/dartlang/vm/service/consumer/GetIsolateConsumer.java
src/org/dartlang/vm/service/consumer/GetIsolateGroupConsumer.java
src/org/dartlang/vm/service/consumer/GetIsolateGroupMemoryUsageConsumer.java
src/org/dartlang/vm/service/consumer/GetMemoryUsageConsumer.java
src/org/dartlang/vm/service/consumer/GetObjectConsumer.java
src/org/dartlang/vm/service/consumer/InstanceSetConsumer.java
Expand Down Expand Up @@ -63,6 +65,8 @@ src/org/dartlang/vm/service/element/InstanceKind.java
src/org/dartlang/vm/service/element/InstanceRef.java
src/org/dartlang/vm/service/element/InstanceSet.java
src/org/dartlang/vm/service/element/Isolate.java
src/org/dartlang/vm/service/element/IsolateGroup.java
src/org/dartlang/vm/service/element/IsolateGroupRef.java
src/org/dartlang/vm/service/element/IsolateRef.java
src/org/dartlang/vm/service/element/Library.java
src/org/dartlang/vm/service/element/LibraryDependency.java
Expand Down
158 changes: 158 additions & 0 deletions pkg/vm_service/lib/vm_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ Map<String, Function> _typeFactories = {
'Instance': Instance.parse,
'@Isolate': IsolateRef.parse,
'Isolate': Isolate.parse,
'@IsolateGroup': IsolateGroupRef.parse,
'IsolateGroup': IsolateGroup.parse,
'InboundReferences': InboundReferences.parse,
'InboundReference': InboundReference.parse,
'InstanceSet': InstanceSet.parse,
Expand Down Expand Up @@ -188,7 +190,9 @@ Map<String, List<String>> _methodReturnTypes = {
'getInboundReferences': const ['InboundReferences', 'Sentinel'],
'getInstances': const ['InstanceSet'],
'getIsolate': const ['Isolate', 'Sentinel'],
'getIsolateGroup': const ['IsolateGroup', 'Sentinel'],
'getMemoryUsage': const ['MemoryUsage', 'Sentinel'],
'getIsolateGroupMemoryUsage': const ['MemoryUsage', 'Sentinel'],
'getScripts': const ['ScriptList'],
'getObject': const ['Obj', 'Sentinel'],
'getRetainingPath': const ['RetainingPath'],
Expand Down Expand Up @@ -506,6 +510,21 @@ abstract class VmServiceInterface {
/// The return value can be one of [Isolate] or [Sentinel].
Future<dynamic> getIsolate(String isolateId);

/// The `getIsolateGroup` RPC is used to lookup an `IsolateGroup` object by
/// its `id`.
///
/// If `isolateGroupId` refers to an isolate group which has exited, then the
/// `Expired` [Sentinel] is returned.
///
/// `IsolateGroup` `id` is an opaque identifier that can be fetched from an
/// `IsolateGroup`. List of active `IsolateGroup`'s, for example, is available
/// on `VM` object.
///
/// See [IsolateGroup], [VM].
///
/// The return value can be one of [IsolateGroup] or [Sentinel].
Future<dynamic> getIsolateGroup(String isolateGroupId);

/// The `getMemoryUsage` RPC is used to lookup an isolate's memory usage
/// statistics by its `id`.
///
Expand All @@ -517,6 +536,17 @@ abstract class VmServiceInterface {
/// The return value can be one of [MemoryUsage] or [Sentinel].
Future<dynamic> getMemoryUsage(String isolateId);

/// The `getIsolateGroupMemoryUsage` RPC is used to lookup an isolate group's
/// memory usage statistics by its `id`.
///
/// If `isolateGroupId` refers to an isolate group which has exited, then the
/// `Expired` [Sentinel] is returned.
///
/// See [IsolateGroup].
///
/// The return value can be one of [MemoryUsage] or [Sentinel].
Future<dynamic> getIsolateGroupMemoryUsage(String isolateGroupId);

/// The `getScripts` RPC is used to retrieve a `ScriptList` containing all
/// scripts for an isolate based on the isolate's `isolateId`.
///
Expand Down Expand Up @@ -1027,11 +1057,21 @@ class VmServerConnection {
params['isolateId'],
);
break;
case 'getIsolateGroup':
response = await _serviceImplementation.getIsolateGroup(
params['isolateGroupId'],
);
break;
case 'getMemoryUsage':
response = await _serviceImplementation.getMemoryUsage(
params['isolateId'],
);
break;
case 'getIsolateGroupMemoryUsage':
response = await _serviceImplementation.getIsolateGroupMemoryUsage(
params['isolateGroupId'],
);
break;
case 'getScripts':
response = await _serviceImplementation.getScripts(
params['isolateId'],
Expand Down Expand Up @@ -1468,11 +1508,22 @@ class VmService implements VmServiceInterface {
return _call('getIsolate', {'isolateId': isolateId});
}

@override
Future<dynamic> getIsolateGroup(String isolateGroupId) {
return _call('getIsolateGroup', {'isolateGroupId': isolateGroupId});
}

@override
Future<dynamic> getMemoryUsage(String isolateId) {
return _call('getMemoryUsage', {'isolateId': isolateId});
}

@override
Future<dynamic> getIsolateGroupMemoryUsage(String isolateGroupId) {
return _call(
'getIsolateGroupMemoryUsage', {'isolateGroupId': isolateGroupId});
}

@override
Future<ScriptList> getScripts(String isolateId) {
return _call('getScripts', {'isolateId': isolateId});
Expand Down Expand Up @@ -1699,6 +1750,7 @@ class VmService implements VmServiceInterface {
void dispose() {
_streamSub.cancel();
_completers.values.forEach((c) => c.completeError('disposed'));
_completers.clear();
if (_disposeHandler != null) {
_disposeHandler();
}
Expand Down Expand Up @@ -4444,6 +4496,105 @@ class Isolate extends Response {
String toString() => '[Isolate]';
}

/// `IsolateGroupRef` is a reference to an `IsolateGroup` object.
class IsolateGroupRef extends Response {
static IsolateGroupRef parse(Map<String, dynamic> json) =>
json == null ? null : IsolateGroupRef._fromJson(json);

/// The id which is passed to the getIsolateGroup RPC to load this isolate
/// group.
String id;

/// A numeric id for this isolate group, represented as a string. Unique.
String number;

/// A name identifying this isolate group. Not guaranteed to be unique.
String name;

IsolateGroupRef({
@required this.id,
@required this.number,
@required this.name,
});
IsolateGroupRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
number = json['number'];
name = json['name'];
}

@override
Map<String, dynamic> toJson() {
var json = <String, dynamic>{};
json['type'] = '@IsolateGroup';
json.addAll({
'id': id,
'number': number,
'name': name,
});
return json;
}

int get hashCode => id.hashCode;

operator ==(other) => other is IsolateGroupRef && id == other.id;

String toString() =>
'[IsolateGroupRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
}

/// An `Isolate` object provides information about one isolate in the VM.
class IsolateGroup extends Response {
static IsolateGroup parse(Map<String, dynamic> json) =>
json == null ? null : IsolateGroup._fromJson(json);

/// The id which is passed to the getIsolate RPC to reload this isolate.
String id;

/// A numeric id for this isolate, represented as a string. Unique.
String number;

/// A name identifying this isolate. Not guaranteed to be unique.
String name;

/// A list of all isolates in this isolate group.
List<IsolateRef> isolates;

IsolateGroup({
@required this.id,
@required this.number,
@required this.name,
@required this.isolates,
});
IsolateGroup._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
number = json['number'];
name = json['name'];
isolates = List<IsolateRef>.from(
createServiceObject(json['isolates'], const ['IsolateRef']));
}

@override
Map<String, dynamic> toJson() {
var json = <String, dynamic>{};
json['type'] = 'IsolateGroup';
json.addAll({
'id': id,
'number': number,
'name': name,
'isolates': isolates.map((f) => f.toJson()).toList(),
});
return json;
}

int get hashCode => id.hashCode;

operator ==(other) => other is IsolateGroup && id == other.id;

String toString() => '[IsolateGroup ' //
'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
'isolates: ${isolates}]';
}

/// See [getInboundReferences].
class InboundReferences extends Response {
static InboundReferences parse(Map<String, dynamic> json) =>
Expand Down Expand Up @@ -6236,6 +6387,9 @@ class VM extends Response {
/// A list of isolates running in the VM.
List<IsolateRef> isolates;

/// A list of isolate groups running in the VM.
List<IsolateGroupRef> isolateGroups;

VM({
@required this.name,
@required this.architectureBits,
Expand All @@ -6246,6 +6400,7 @@ class VM extends Response {
@required this.pid,
@required this.startTime,
@required this.isolates,
@required this.isolateGroups,
});
VM._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
Expand All @@ -6258,6 +6413,8 @@ class VM extends Response {
startTime = json['startTime'];
isolates = List<IsolateRef>.from(
createServiceObject(json['isolates'], const ['IsolateRef']));
isolateGroups = List<IsolateGroupRef>.from(
createServiceObject(json['isolateGroups'], const ['IsolateGroupRef']));
}

@override
Expand All @@ -6274,6 +6431,7 @@ class VM extends Response {
'pid': pid,
'startTime': startTime,
'isolates': isolates.map((f) => f.toJson()).toList(),
'isolateGroups': isolateGroups.map((f) => f.toJson()).toList(),
});
return json;
}
Expand Down
35 changes: 35 additions & 0 deletions pkg/vm_service/test/get_isolate_group_memory_usage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';

import 'common/test_helper.dart';

var tests = <VMTest>[
(VmService service) async {
final vm = await service.getVM();
final result =
await service.getIsolateGroupMemoryUsage(vm.isolateGroups.first.id);
expect(result.heapUsage, isPositive);
expect(result.heapCapacity, isPositive);
expect(result.externalUsage, isNonNegative);
},
(VmService service) async {
bool caughtException;
try {
await service.getMemoryUsage('badid');
fail('Unreachable');
} on RPCError catch (e) {
caughtException = true;
expect(
e.details,
contains(
"getMemoryUsage: invalid 'isolateGroupId' parameter: badid"));
}
expect(caughtException, isTrue);
},
];

main(args) async => runVMTests(args, tests);
5 changes: 5 additions & 0 deletions runtime/observatory/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ analyzer:
- tests/service/get_isolate_after_language_error_test.dart
- tests/service/get_user_level_retaining_path_rpc_test.dart
- tests/service/pause_on_unhandled_async_exceptions_test.dart

linter:
rules:
- prefer_final_fields
- prefer_final_locals
2 changes: 2 additions & 0 deletions runtime/observatory/lib/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ part 'src/models/objects/icdata.dart';
part 'src/models/objects/inbound_references.dart';
part 'src/models/objects/instance.dart';
part 'src/models/objects/isolate.dart';
part 'src/models/objects/isolate_group.dart';
part 'src/models/objects/library.dart';
part 'src/models/objects/local_var_descriptors.dart';
part 'src/models/objects/map_association.dart';
Expand Down Expand Up @@ -74,6 +75,7 @@ part 'src/models/repositories/icdata.dart';
part 'src/models/repositories/inbound_references.dart';
part 'src/models/repositories/instance.dart';
part 'src/models/repositories/isolate.dart';
part 'src/models/repositories/isolate_group.dart';
part 'src/models/repositories/library.dart';
part 'src/models/repositories/megamorphiccache.dart';
part 'src/models/repositories/metric.dart';
Expand Down
1 change: 1 addition & 0 deletions runtime/observatory/lib/repositories.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ part 'src/repositories/icdata.dart';
part 'src/repositories/inbound_references.dart';
part 'src/repositories/instance.dart';
part 'src/repositories/isolate.dart';
part 'src/repositories/isolate_group.dart';
part 'src/repositories/library.dart';
part 'src/repositories/megamorphiccache.dart';
part 'src/repositories/metric.dart';
Expand Down
Loading

0 comments on commit 9e636b5

Please sign in to comment.