1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-03 00:08:46 +00:00

Reland "[ Service / dart:isolate ] Added getPorts RPC and 'debugName' optional"

This reverts commit f78c40e32a.

Change-Id: Id838b39afcb371d3b50f0009322ecf0fb2080894
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169461
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2020-10-29 02:52:03 +00:00 committed by commit-bot@chromium.org
parent 2672eb34f6
commit d5118d5fc8
35 changed files with 489 additions and 64 deletions

View File

@ -4,8 +4,14 @@
#### `dart:io`
* `HttpRequest` will now correctly follow HTTP 308 redirects
(`HttpStatus.permanentRedirect`).
* `HttpRequest` will now correctly follow HTTP 308 redirects
(`HttpStatus.permanentRedirect`).
#### `dart:isolate`
* Added `debugName` positional parameter to `ReceivePort` and `RawReceivePort`
constructors, a name which can be associated with the port and displayed in
tooling.
### Dart VM

View File

@ -1,4 +1,12 @@
# Changelog
## 5.4.0
- Update to version `3.41.0` of the spec.
- Added `PortList` class.
- Added `getPorts` RPC.
- Added optional properties `portId`, `allocationLocation`, and `debugName` to
`InstanceRef` and `Instance`.
## 5.3.1
- Rename `State` class to `_State` to avoid class name conflicts with Flutter.
@ -6,7 +14,6 @@
- Added support for `dart:io` extensions version 1.5.
- Added combination getter/setter `socketProfilingEnabled`.
- Deprecated `startSocketProfiling` and `pauseSocketProfiling`.
- Added support for `dart:io` extensions version 1.4.
- Update to version `3.40.0` of the spec.
- Added `IsolateFlag` class.
- Added `isolateFlags` property to `Isolate`.

View File

@ -192,6 +192,7 @@ String assertInstanceKind(String obj) {
if (obj == "MirrorReference") return obj;
if (obj == "Null") return obj;
if (obj == "PlainInstance") return obj;
if (obj == "ReceivePort") return obj;
if (obj == "RegExp") return obj;
if (obj == "StackTrace") return obj;
if (obj == "String") return obj;
@ -912,6 +913,13 @@ vms.Obj assertObj(vms.Obj obj) {
return obj;
}
vms.PortList assertPortList(vms.PortList obj) {
assertNotNull(obj);
assertString(obj.type);
assertListOfInstanceRef(obj.ports);
return obj;
}
vms.ProfileFunction assertProfileFunction(vms.ProfileFunction obj) {
assertNotNull(obj);
assertString(obj.kind);

View File

@ -25,6 +25,7 @@ src/org/dartlang/vm/service/consumer/GetStackConsumer.java
src/org/dartlang/vm/service/consumer/InvokeConsumer.java
src/org/dartlang/vm/service/consumer/KillConsumer.java
src/org/dartlang/vm/service/consumer/PauseConsumer.java
src/org/dartlang/vm/service/consumer/PortListConsumer.java
src/org/dartlang/vm/service/consumer/ProcessMemoryUsageConsumer.java
src/org/dartlang/vm/service/consumer/ProtocolListConsumer.java
src/org/dartlang/vm/service/consumer/ReloadSourcesConsumer.java
@ -95,6 +96,7 @@ src/org/dartlang/vm/service/element/Null.java
src/org/dartlang/vm/service/element/NullRef.java
src/org/dartlang/vm/service/element/Obj.java
src/org/dartlang/vm/service/element/ObjRef.java
src/org/dartlang/vm/service/element/PortList.java
src/org/dartlang/vm/service/element/ProcessMemoryItem.java
src/org/dartlang/vm/service/element/ProcessMemoryUsage.java
src/org/dartlang/vm/service/element/ProfileFunction.java

View File

@ -1 +1 @@
version=3.40
version=3.41

View File

@ -28,7 +28,7 @@ export 'snapshot_graph.dart'
HeapSnapshotObjectNoData,
HeapSnapshotObjectNullData;
const String vmServiceVersion = '3.40.0';
const String vmServiceVersion = '3.41.0';
/// @optional
const String optional = 'optional';
@ -157,6 +157,7 @@ Map<String, Function> _typeFactories = {
'Null': NullVal.parse,
'@Object': ObjRef.parse,
'Object': Obj.parse,
'PortList': PortList.parse,
'ProfileFunction': ProfileFunction.parse,
'ProtocolList': ProtocolList.parse,
'Protocol': Protocol.parse,
@ -209,6 +210,7 @@ Map<String, List<String>> _methodReturnTypes = {
'getIsolateGroupMemoryUsage': const ['MemoryUsage'],
'getScripts': const ['ScriptList'],
'getObject': const ['Obj'],
'getPorts': const ['PortList'],
'getRetainingPath': const ['RetainingPath'],
'getProcessMemoryUsage': const ['ProcessMemoryUsage'],
'getStack': const ['Stack'],
@ -688,6 +690,12 @@ abstract class VmServiceInterface {
int count,
});
/// The `getPorts` RPC is used to retrieve the list of `ReceivePort` instances
/// for a given isolate.
///
/// See [PortList].
Future<PortList> getPorts(String isolateId);
/// The `getRetainingPath` RPC is used to lookup a path from an object
/// specified by `targetId` to a GC root (i.e., the object which is preventing
/// this object from being garbage collected).
@ -1318,6 +1326,11 @@ class VmServerConnection {
count: params['count'],
);
break;
case 'getPorts':
response = await _serviceImplementation.getPorts(
params['isolateId'],
);
break;
case 'getRetainingPath':
response = await _serviceImplementation.getRetainingPath(
params['isolateId'],
@ -1770,6 +1783,10 @@ class VmService implements VmServiceInterface {
if (count != null) 'count': count,
});
@override
Future<PortList> getPorts(String isolateId) =>
_call('getPorts', {'isolateId': isolateId});
@override
Future<RetainingPath> getRetainingPath(
String isolateId, String targetId, int limit) =>
@ -2432,6 +2449,9 @@ class InstanceKind {
/// An instance of the Dart class BoundedType.
static const String kBoundedType = 'BoundedType';
/// An instance of the Dart class ReceivePort.
static const String kReceivePort = 'ReceivePort';
}
/// A `SentinelKind` is used to distinguish different kinds of `Sentinel`
@ -4239,6 +4259,27 @@ class InstanceRef extends ObjRef {
@optional
ContextRef closureContext;
/// The port ID for a ReceivePort.
///
/// Provided for instance kinds:
/// - ReceivePort
@optional
int portId;
/// The stack trace associated with the allocation of a ReceivePort.
///
/// Provided for instance kinds:
/// - ReceivePort
@optional
InstanceRef allocationLocation;
/// A name associated with a ReceivePort used for debugging purposes.
///
/// Provided for instance kinds:
/// - ReceivePort
@optional
String debugName;
InstanceRef({
@required this.kind,
@required this.classRef,
@ -4252,6 +4293,9 @@ class InstanceRef extends ObjRef {
this.pattern,
this.closureFunction,
this.closureContext,
this.portId,
this.allocationLocation,
this.debugName,
}) : super(id: id);
InstanceRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
@ -4269,6 +4313,10 @@ class InstanceRef extends ObjRef {
createServiceObject(json['closureFunction'], const ['FuncRef']);
closureContext =
createServiceObject(json['closureContext'], const ['ContextRef']);
portId = json['portId'];
allocationLocation =
createServiceObject(json['allocationLocation'], const ['InstanceRef']);
debugName = json['debugName'];
}
@override
@ -4288,6 +4336,9 @@ class InstanceRef extends ObjRef {
_setIfNotNull(json, 'pattern', pattern?.toJson());
_setIfNotNull(json, 'closureFunction', closureFunction?.toJson());
_setIfNotNull(json, 'closureContext', closureContext?.toJson());
_setIfNotNull(json, 'portId', portId);
_setIfNotNull(json, 'allocationLocation', allocationLocation?.toJson());
_setIfNotNull(json, 'debugName', debugName);
return json;
}
@ -4318,6 +4369,7 @@ class Instance extends Obj implements InstanceRef {
/// - Double (suitable for passing to Double.parse())
/// - Int (suitable for passing to int.parse())
/// - String (value may be truncated)
/// - StackTrace
@optional
String valueAsString;
@ -4554,6 +4606,27 @@ class Instance extends Obj implements InstanceRef {
@optional
InstanceRef bound;
/// The port ID for a ReceivePort.
///
/// Provided for instance kinds:
/// - ReceivePort
@optional
int portId;
/// The stack trace associated with the allocation of a ReceivePort.
///
/// Provided for instance kinds:
/// - ReceivePort
@optional
InstanceRef allocationLocation;
/// A name associated with a ReceivePort used for debugging purposes.
///
/// Provided for instance kinds:
/// - ReceivePort
@optional
String debugName;
Instance({
@required this.kind,
@required this.classRef,
@ -4582,6 +4655,9 @@ class Instance extends Obj implements InstanceRef {
this.parameterIndex,
this.targetType,
this.bound,
this.portId,
this.allocationLocation,
this.debugName,
}) : super(id: id);
Instance._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
@ -4627,6 +4703,10 @@ class Instance extends Obj implements InstanceRef {
parameterIndex = json['parameterIndex'];
targetType = createServiceObject(json['targetType'], const ['InstanceRef']);
bound = createServiceObject(json['bound'], const ['InstanceRef']);
portId = json['portId'];
allocationLocation =
createServiceObject(json['allocationLocation'], const ['InstanceRef']);
debugName = json['debugName'];
}
@override
@ -4663,6 +4743,9 @@ class Instance extends Obj implements InstanceRef {
_setIfNotNull(json, 'parameterIndex', parameterIndex);
_setIfNotNull(json, 'targetType', targetType?.toJson());
_setIfNotNull(json, 'bound', bound?.toJson());
_setIfNotNull(json, 'portId', portId);
_setIfNotNull(json, 'allocationLocation', allocationLocation?.toJson());
_setIfNotNull(json, 'debugName', debugName);
return json;
}
@ -5743,6 +5826,37 @@ class Obj extends Response implements ObjRef {
String toString() => '[Obj type: ${type}, id: ${id}]';
}
/// A `PortList` contains a list of ports associated with some isolate.
///
/// See [getPort].
class PortList extends Response {
static PortList parse(Map<String, dynamic> json) =>
json == null ? null : PortList._fromJson(json);
List<InstanceRef> ports;
PortList({
@required this.ports,
});
PortList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
ports = List<InstanceRef>.from(
createServiceObject(json['ports'], const ['InstanceRef']) ?? []);
}
@override
Map<String, dynamic> toJson() {
var json = <String, dynamic>{};
json['type'] = 'PortList';
json.addAll({
'ports': ports.map((f) => f.toJson()).toList(),
});
return json;
}
String toString() => '[PortList type: ${type}, ports: ${ports}]';
}
/// A `ProfileFunction` contains profiling information about a Dart or native
/// function.
///

View File

@ -2,7 +2,7 @@ name: vm_service
description: >-
A library to communicate with a service implementing the Dart VM
service protocol.
version: 5.3.1
version: 5.4.0
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service

View File

@ -51,11 +51,12 @@ DEFINE_NATIVE_ENTRY(CapabilityImpl_get_hashcode, 0, 1) {
return Smi::New(hash);
}
DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 0, 1) {
DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 0, 2) {
ASSERT(
TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
GET_NON_NULL_NATIVE_ARGUMENT(String, debug_name, arguments->NativeArgAt(1));
Dart_Port port_id = PortMap::CreatePort(isolate->message_handler());
return ReceivePort::New(port_id, false /* not control port */);
return ReceivePort::New(port_id, debug_name, false /* not control port */);
}
DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_id, 0, 1) {

View File

@ -214,4 +214,12 @@ const StackTrace& GetCurrentStackTrace(int skip_frames) {
return stacktrace;
}
bool HasStack() {
Thread* thread = Thread::Current();
StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread,
StackFrameIterator::kNoCrossThreadIteration);
StackFrame* frame = frames.NextFrame();
return frame != nullptr;
}
} // namespace dart

View File

@ -21,6 +21,9 @@ const StackTrace& GetCurrentStackTrace(int skip_frames);
// Creates a StackTrace object to be attached to an exception.
StackTracePtr GetStackTraceForException();
// Returns false if there is no Dart stack available.
bool HasStack();
} // namespace dart
#endif // RUNTIME_LIB_STACKTRACE_H_

View File

@ -120,6 +120,9 @@ enum InstanceKind {
/// An instance of the Dart class TypeRef.
typeRef,
/// An instance of the Dart class RawReceivePort
receivePort,
}
bool isTypedData(InstanceKind? kind) {

View File

@ -2781,6 +2781,8 @@ M.InstanceKind stringToInstanceKind(String s) {
return M.InstanceKind.typeParameter;
case 'TypeRef':
return M.InstanceKind.typeRef;
case 'ReceivePort':
return M.InstanceKind.receivePort;
}
var message = 'Unrecognized instance kind: $s';
Logger.root.severe(message);

View File

@ -0,0 +1,50 @@
// Copyright (c) 2020, 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 'dart:isolate' hide Isolate;
import 'package:observatory/service_io.dart';
import 'package:test/test.dart';
import 'test_helper.dart';
var port1;
var port2;
var port3;
void warmup() {
port1 = RawReceivePort(null, 'port1');
port2 = RawReceivePort((_) {});
port3 = RawReceivePort((_) {}, 'port3');
port3.close();
RawReceivePort((_) {}, 'port4');
}
int countNameMatches(ports, name) {
var matches = 0;
for (var port in ports) {
if (port['debugName'] == name) {
matches++;
}
}
return matches;
}
final tests = <IsolateTest>[
(Isolate isolate) async {
dynamic result = await isolate.invokeRpcNoUpgrade('getPorts', {});
expect(result['type'], 'PortList');
expect(result['ports'], isList);
final ports = result['ports'];
// There are at least three ports: the three created in warm up that
// weren't closed. Some OSes will have other ports open but we do not try
// and test for these.
expect(ports.length, greaterThanOrEqualTo(3));
expect(countNameMatches(ports, 'port1'), 1);
expect(countNameMatches(ports, 'port3'), 0);
expect(countNameMatches(ports, 'port4'), 1);
expect(countNameMatches(ports, ''), greaterThanOrEqualTo(1));
},
];
main(args) async => runIsolateTests(args, tests, testeeBefore: warmup);

View File

@ -9,12 +9,12 @@ import 'test_helper.dart';
var tests = <VMTest>[
(VM vm) async {
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
expect(result['minor'], equals(40));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], 'Version');
expect(result['major'], 3);
expect(result['minor'], 41);
expect(result['_privateMajor'], 0);
expect(result['_privateMinor'], 0);
},
];

View File

@ -120,6 +120,9 @@ enum InstanceKind {
/// An instance of the Dart class TypeRef.
typeRef,
/// An instance of the Dart class RawReceivePort
receivePort,
}
bool isTypedData(InstanceKind kind) {

View File

@ -2790,6 +2790,8 @@ M.InstanceKind stringToInstanceKind(String s) {
return M.InstanceKind.typeParameter;
case 'TypeRef':
return M.InstanceKind.typeRef;
case 'ReceivePort':
return M.InstanceKind.receivePort;
}
var message = 'Unrecognized instance kind: $s';
Logger.root.severe(message);

View File

@ -0,0 +1,50 @@
// Copyright (c) 2020, 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 'dart:isolate' hide Isolate;
import 'package:observatory_2/service_io.dart';
import 'package:test/test.dart';
import 'test_helper.dart';
var port1;
var port2;
var port3;
void warmup() {
port1 = RawReceivePort(null, 'port1');
port2 = RawReceivePort((_) {});
port3 = RawReceivePort((_) {}, 'port3');
port3.close();
RawReceivePort((_) {}, 'port4');
}
int countNameMatches(ports, name) {
var matches = 0;
for (var port in ports) {
if (port['debugName'] == name) {
matches++;
}
}
return matches;
}
final tests = <IsolateTest>[
(Isolate isolate) async {
dynamic result = await isolate.invokeRpcNoUpgrade('getPorts', {});
expect(result['type'], 'PortList');
expect(result['ports'], isList);
final ports = result['ports'];
// There are at least three ports: the three created in warm up that
// weren't closed. Some OSes will have other ports open but we do not try
// and test for these.
expect(ports.length, greaterThanOrEqualTo(3));
expect(countNameMatches(ports, 'port1'), 1);
expect(countNameMatches(ports, 'port3'), 0);
expect(countNameMatches(ports, 'port4'), 1);
expect(countNameMatches(ports, ''), greaterThanOrEqualTo(1));
},
];
main(args) async => runIsolateTests(args, tests, testeeBefore: warmup);

View File

@ -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(40));
expect(result['minor'], equals(41));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},

View File

@ -54,7 +54,7 @@ namespace dart {
V(CapabilityImpl_factory, 1) \
V(CapabilityImpl_equals, 2) \
V(CapabilityImpl_get_hashcode, 1) \
V(RawReceivePortImpl_factory, 1) \
V(RawReceivePortImpl_factory, 2) \
V(RawReceivePortImpl_get_id, 1) \
V(RawReceivePortImpl_get_sendport, 1) \
V(RawReceivePortImpl_closeInternal, 1) \

View File

@ -497,7 +497,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
@ -1017,7 +1017,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 96;
@ -1528,7 +1528,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
@ -2049,7 +2049,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 96;
@ -2559,7 +2559,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
@ -3073,7 +3073,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 96;
@ -3578,7 +3578,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 16;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
@ -4093,7 +4093,7 @@ static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RedirectionData_InstanceSize = 32;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 96;
@ -4659,7 +4659,7 @@ static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 12;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
16;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
@ -5233,7 +5233,7 @@ static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
32;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
@ -5811,7 +5811,7 @@ static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
32;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
@ -6377,7 +6377,7 @@ static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 12;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
16;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
@ -6944,7 +6944,7 @@ static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
32;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
@ -7515,7 +7515,7 @@ static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_RedirectionData_InstanceSize =
32;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;

View File

@ -725,6 +725,31 @@ ObjectPtr DartLibraryCalls::LookupHandler(Dart_Port port_id) {
return result.raw();
}
ObjectPtr DartLibraryCalls::LookupOpenPorts() {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Function& function = Function::Handle(
zone, thread->isolate()->object_store()->lookup_open_ports());
const int kTypeArgsLen = 0;
const int kNumArguments = 0;
if (function.IsNull()) {
Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
ASSERT(!isolate_lib.IsNull());
const String& class_name = String::Handle(
zone, isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
const String& function_name = String::Handle(
zone, isolate_lib.PrivateName(Symbols::_lookupOpenPorts()));
function = Resolver::ResolveStatic(isolate_lib, class_name, function_name,
kTypeArgsLen, kNumArguments,
Object::empty_array());
ASSERT(!function.IsNull());
thread->isolate()->object_store()->set_lookup_open_ports(function);
}
const Object& result = Object::Handle(
zone, DartEntry::InvokeFunction(function, Object::empty_array()));
return result.raw();
}
ObjectPtr DartLibraryCalls::HandleMessage(const Object& handler,
const Instance& message) {
Thread* thread = Thread::Current();

View File

@ -282,6 +282,9 @@ class DartLibraryCalls : public AllStatic {
// Returns the handler if one has been registered for this port id.
static ObjectPtr LookupHandler(Dart_Port port_id);
// Returns a list of open ReceivePorts.
static ObjectPtr LookupOpenPorts();
// Returns null on success, a RawError on failure.
static ObjectPtr HandleMessage(const Object& handler,
const Instance& dart_message);

View File

@ -2385,8 +2385,9 @@ static MessageHandler::MessageStatus RunIsolate(uword parameter) {
args.SetAt(2, Instance::Handle(state->BuildArgs(thread)));
args.SetAt(3, Instance::Handle(state->BuildMessage(thread)));
args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False());
args.SetAt(5, ReceivePort::Handle(ReceivePort::New(
isolate->main_port(), true /* control port */)));
args.SetAt(5, ReceivePort::Handle(
ReceivePort::New(isolate->main_port(), Symbols::Empty(),
true /* control port */)));
args.SetAt(6, capabilities);
const Library& lib = Library::Handle(Library::IsolateLibrary());

View File

@ -7,6 +7,7 @@
#include <memory>
#include "include/dart_api.h"
#include "lib/stacktrace.h"
#include "platform/assert.h"
#include "platform/text_buffer.h"
#include "platform/unaligned.h"
@ -23805,6 +23806,7 @@ const char* Capability::ToCString() const {
}
ReceivePortPtr ReceivePort::New(Dart_Port id,
const String& debug_name,
bool is_control_port,
Heap::Space space) {
ASSERT(id != ILLEGAL_PORT);
@ -23812,6 +23814,8 @@ ReceivePortPtr ReceivePort::New(Dart_Port id,
Zone* zone = thread->zone();
const SendPort& send_port =
SendPort::Handle(zone, SendPort::New(id, thread->isolate()->origin_id()));
const StackTrace& allocation_location_ =
HasStack() ? GetCurrentStackTrace(0) : StackTrace::Handle();
ReceivePort& result = ReceivePort::Handle(zone);
{
@ -23820,6 +23824,9 @@ ReceivePortPtr ReceivePort::New(Dart_Port id,
NoSafepointScope no_safepoint;
result ^= raw;
result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw());
result.StorePointer(&result.raw_ptr()->debug_name_, debug_name.raw());
result.StorePointer(&result.raw_ptr()->allocation_location_,
allocation_location_.raw());
}
if (is_control_port) {
PortMap::SetPortState(id, PortMap::kControlPort);

View File

@ -10567,10 +10567,17 @@ class ReceivePort : public Instance {
InstancePtr handler() const { return raw_ptr()->handler_; }
void set_handler(const Instance& value) const;
StackTracePtr allocation_location() const {
return raw_ptr()->allocation_location_;
}
StringPtr debug_name() const { return raw_ptr()->debug_name_; }
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(ReceivePortLayout));
}
static ReceivePortPtr New(Dart_Port id,
const String& debug_name,
bool is_control_port,
Heap::Space space = Heap::kNew);

View File

@ -1452,7 +1452,15 @@ void Capability::PrintJSONImpl(JSONStream* stream, bool ref) const {
}
void ReceivePort::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
JSONObject obj(stream);
Instance::PrintSharedInstanceJSON(&obj, ref);
const StackTrace& allocation_location_ =
StackTrace::Handle(allocation_location());
const String& debug_name_ = String::Handle(debug_name());
obj.AddProperty("kind", "ReceivePort");
obj.AddProperty64("portId", Id());
obj.AddProperty("debugName", debug_name_.ToCString());
obj.AddProperty("allocationLocation", allocation_location_);
}
void SendPort::PrintJSONImpl(JSONStream* stream, bool ref) const {

View File

@ -160,6 +160,7 @@ class ObjectPointerVisitor;
RW(Instance, stack_overflow) \
RW(Instance, out_of_memory) \
RW(Function, lookup_port_handler) \
RW(Function, lookup_open_ports) \
RW(Function, handle_message_function) \
RW(Function, growable_list_factory) \
RW(Function, simple_instance_of_function) \

View File

@ -2726,7 +2726,9 @@ class ReceivePortLayout : public InstanceLayout {
VISIT_FROM(ObjectPtr, send_port_)
SendPortPtr send_port_;
InstancePtr handler_;
VISIT_TO(ObjectPtr, handler_)
StringPtr debug_name_;
StackTracePtr allocation_location_;
VISIT_TO(ObjectPtr, allocation_location_)
};
class TransferableTypedDataLayout : public InstanceLayout {

View File

@ -171,6 +171,8 @@ namespace dart {
F(ExternalTypedData, length_) \
F(ReceivePort, send_port_) \
F(ReceivePort, handler_) \
F(ReceivePort, debug_name_) \
F(ReceivePort, allocation_location_) \
F(StackTrace, async_link_) \
F(StackTrace, code_array_) \
F(StackTrace, pc_offset_array_) \

View File

@ -3142,6 +3142,30 @@ static bool GetInstances(Thread* thread, JSONStream* js) {
return true;
}
static const MethodParameter* get_ports_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
NULL,
};
static bool GetPorts(Thread* thread, JSONStream* js) {
// Ensure the array and handles created below are promptly destroyed.
StackZone zone(thread);
HANDLESCOPE(thread);
const GrowableObjectArray& ports = GrowableObjectArray::Handle(
GrowableObjectArray::RawCast(DartLibraryCalls::LookupOpenPorts()));
JSONObject jsobj(js);
jsobj.AddProperty("type", "PortList");
{
Instance& port = Instance::Handle(zone.GetZone());
JSONArray arr(&jsobj, "ports");
for (int i = 0; i < ports.Length(); ++i) {
port ^= ports.At(i);
arr.AddValue(port);
}
}
return true;
}
#if !defined(DART_PRECOMPILED_RUNTIME)
static const char* const report_enum_names[] = {
SourceReport::kCallSitesStr,
@ -4389,12 +4413,12 @@ static bool GetPersistentHandles(Thread* thread, JSONStream* js) {
return true;
}
static const MethodParameter* get_ports_params[] = {
static const MethodParameter* get_ports_private_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
NULL,
};
static bool GetPorts(Thread* thread, JSONStream* js) {
static bool GetPortsPrivate(Thread* thread, JSONStream* js) {
MessageHandler* message_handler = thread->isolate()->message_handler();
PortMap::PrintPortsForMessageHandler(message_handler, js);
return true;
@ -5054,6 +5078,8 @@ static const ServiceMethodDescriptor service_methods_[] = {
get_inbound_references_params },
{ "getInstances", GetInstances,
get_instances_params },
{ "getPorts", GetPorts,
get_ports_params },
{ "getIsolate", GetIsolate,
get_isolate_params },
{ "_getIsolateObjectStore", GetIsolateObjectStore,
@ -5074,8 +5100,8 @@ static const ServiceMethodDescriptor service_methods_[] = {
get_object_store_params },
{ "_getPersistentHandles", GetPersistentHandles,
get_persistent_handles_params, },
{ "_getPorts", GetPorts,
get_ports_params },
{ "_getPorts", GetPortsPrivate,
get_ports_private_params },
{ "getProcessMemoryUsage", GetProcessMemoryUsage,
get_process_memory_usage_params },
{ "_getReachableSize", GetReachableSize,

View File

@ -15,7 +15,7 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
#define SERVICE_PROTOCOL_MINOR_VERSION 40
#define SERVICE_PROTOCOL_MINOR_VERSION 41
class Array;
class EmbedderServiceHandler;

View File

@ -1,8 +1,8 @@
# Dart VM Service Protocol 3.40
# Dart VM Service Protocol 3.41
> Please post feedback to the [observatory-discuss group][discuss-list]
This document describes of _version 3.40_ of the Dart VM Service Protocol. This
This document describes of _version 3.41_ 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.
@ -47,6 +47,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
- [getIsolateGroup](#getisolategroup)
- [getMemoryUsage](#getmemoryusage)
- [getObject](#getobject)
- [getPorts](#getports)
- [getProcessMemoryUsage](#getprocessmemoryusage)
- [getRetainingPath](#getretainingpath)
- [getScripts](#getscripts)
@ -113,6 +114,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
- [NativeFunction](#nativefunction)
- [Null](#null)
- [Object](#object)
- [PortList](#portlist)
- [ReloadReport](#reloadreport)
- [Response](#response)
- [RetainingObject](#retainingobject)
@ -936,6 +938,17 @@ Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
Float32x4List, and Float64x2List. These parameters are otherwise
ignored.
### getPorts
```
PortList getPorts(string isolateId)
```
The _getPorts_ RPC is used to retrieve the list of `ReceivePort` instances for a
given isolate.
See [PortList](#portlist).
### getRetainingPath
```
@ -2426,6 +2439,24 @@ class @Instance extends @Object {
// Provided for instance kinds:
// Closure
@Context closureContext [optional];
// The port ID for a ReceivePort.
//
// Provided for instance kinds:
// ReceivePort
int portId [optional];
// The stack trace associated with the allocation of a ReceivePort.
//
// Provided for instance kinds:
// ReceivePort
@Instance allocationLocation [optional];
// A name associated with a ReceivePort used for debugging purposes.
//
// Provided for instance kinds:
// ReceivePort
string debugName [optional];
}
```
@ -2446,6 +2477,7 @@ class Instance extends Object {
// Double (suitable for passing to Double.parse())
// Int (suitable for passing to int.parse())
// String (value may be truncated)
// StackTrace
string valueAsString [optional];
// The valueAsString for String references may be truncated. If so,
@ -2658,6 +2690,24 @@ class Instance extends Object {
// BoundedType
// TypeParameter
@Instance bound [optional];
// The port ID for a ReceivePort.
//
// Provided for instance kinds:
// ReceivePort
int portId [optional];
// The stack trace associated with the allocation of a ReceivePort.
//
// Provided for instance kinds:
// ReceivePort
@Instance allocationLocation [optional];
// A name associated with a ReceivePort used for debugging purposes.
//
// Provided for instance kinds:
// ReceivePort
string debugName [optional];
}
```
@ -2742,6 +2792,9 @@ enum InstanceKind {
// An instance of the Dart class BoundedType.
BoundedType,
// An instance of the Dart class ReceivePort.
ReceivePort,
}
```
@ -3184,6 +3237,18 @@ class Object extends Response {
An _Object_ is a persistent object that is owned by some isolate.
### PortList
```
class PortList extends Response {
@Instance[] ports;
}
```
A _PortList_ contains a list of ports associated with some isolate.
See [getPort](#getPort).
### ProfileFunction
```
@ -3855,5 +3920,6 @@ version | comments
3.38 | Added `isSystemIsolate` property to `@Isolate` and `Isolate`, `isSystemIsolateGroup` property to `@IsolateGroup` and `IsolateGroup`, and properties `systemIsolates` and `systemIsolateGroups` to `VM`.
3.39 | Removed the following deprecated RPCs and objects: `getClientName`, `getWebSocketTarget`, `setClientName`, `requireResumeApproval`, `ClientName`, and `WebSocketTarget`.
3.40 | Added `IsolateFlag` object and `isolateFlags` property to `Isolate`.
3.41 | Added `PortList` object, `ReceivePort` `InstanceKind`, and `getPorts` RPC.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss

View File

@ -447,6 +447,7 @@ class ObjectPointerVisitor;
V(_handleMessage, "_handleMessage") \
V(_instanceOf, "_instanceOf") \
V(_lookupHandler, "_lookupHandler") \
V(_lookupOpenPorts, "_lookupOpenPorts") \
V(_name, "_name") \
V(_onData, "_onData") \
V(_rehashObjects, "_rehashObjects") \

View File

@ -22,7 +22,8 @@ import "dart:_internal" show spawnFunction;
@patch
class ReceivePort {
@patch
factory ReceivePort() => new _ReceivePortImpl();
factory ReceivePort([String debugName = '']) =>
new _ReceivePortImpl(debugName);
@patch
factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
@ -62,15 +63,16 @@ class RawReceivePort {
* event is received.
*/
@patch
factory RawReceivePort([Function? handler]) {
_RawReceivePortImpl result = new _RawReceivePortImpl();
factory RawReceivePort([Function? handler, String debugName = '']) {
_RawReceivePortImpl result = new _RawReceivePortImpl(debugName);
result.handler = handler;
return result;
}
}
class _ReceivePortImpl extends Stream implements ReceivePort {
_ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort());
_ReceivePortImpl([String debugName = ''])
: this.fromRawReceivePort(new RawReceivePort(null, debugName));
_ReceivePortImpl.fromRawReceivePort(this._rawPort)
: _controller = new StreamController(sync: true) {
@ -128,11 +130,20 @@ Function _getIsolateScheduleImmediateClosure() {
@pragma("vm:entry-point")
class _RawReceivePortImpl implements RawReceivePort {
factory _RawReceivePortImpl() native "RawReceivePortImpl_factory";
factory _RawReceivePortImpl(String debugName) {
final port = _RawReceivePortImpl._(debugName);
_portMap[port._get_id()] = <String, dynamic>{
'port': port,
};
return port;
}
factory _RawReceivePortImpl._(String debugName)
native "RawReceivePortImpl_factory";
close() {
// Close the port and remove it from the handler map.
_handlerMap.remove(this._closeInternal());
_portMap.remove(this._closeInternal());
}
SendPort get sendPort {
@ -155,10 +166,15 @@ class _RawReceivePortImpl implements RawReceivePort {
// Called from the VM to retrieve the handler for a message.
@pragma("vm:entry-point", "call")
static _lookupHandler(int id) {
var result = _handlerMap[id];
var result = _portMap[id]?['handler'];
return result;
}
@pragma("vm:entry-point", "call")
static _lookupOpenPorts() {
return _portMap.values.map((e) => e['port']).toList();
}
// Called from the VM to dispatch to the handler.
@pragma("vm:entry-point", "call")
static void _handleMessage(Function handler, var message) {
@ -173,22 +189,16 @@ class _RawReceivePortImpl implements RawReceivePort {
_closeInternal() native "RawReceivePortImpl_closeInternal";
void set handler(Function? value) {
_handlerMap[this._get_id()] = value;
final id = this._get_id();
if (!_portMap.containsKey(id)) {
_portMap[id] = <String, dynamic>{
'port': this,
};
}
_portMap[id]!['handler'] = value;
}
// TODO(iposva): Ideally keep this map in the VM.
// id to handler mapping.
static _initHandlerMap() {
// TODO(18511): Workaround bad CheckSmi hoisting.
var tempMap = new HashMap();
// Collect feedback that not all keys are Smis.
tempMap["."] = 1;
tempMap["."] = 2;
return new HashMap();
}
static final Map _handlerMap = _initHandlerMap();
static final _portMap = <dynamic, Map<String, dynamic>>{};
}
@pragma("vm:entry-point")

View File

@ -671,9 +671,12 @@ abstract class ReceivePort implements Stream<dynamic> {
* receive messages. See [Stream.asBroadcastStream] for transforming the port
* to a broadcast stream.
*
* The optional `debugName` parameter can be set to associate a name with
* this port that can be displayed in tooling.
*
* A receive port is closed by canceling its subscription.
*/
external factory ReceivePort();
external factory ReceivePort([String debugName = '']);
/**
* Creates a [ReceivePort] from a [RawReceivePort].
@ -718,8 +721,12 @@ abstract class RawReceivePort {
* A [RawReceivePort] is low level and does not work with [Zone]s. It
* can not be paused. The data-handler must be set before the first
* event is received.
*
* The optional `debugName` parameter can be set to associate a name with
* this port that can be displayed in tooling.
*
*/
external factory RawReceivePort([Function? handler]);
external factory RawReceivePort([Function? handler, String debugName = '']);
/**
* Sets the handler that is invoked for every incoming message.