Skip to content

Commit 56403a0

Browse files
aamcommit-bot@chromium.org
authored and
commit-bot@chromium.org
committed
[vm/sendandexit] Introduce Isolate.exit([port, message]).
This exits current isolate immediately. If [port] is provided, then [message] is verified and sent out as isolate exits. TEST=ci Fixes #47164 Change-Id: I513f4d7ceb5d74820f4aee60f5799b7b5193f2e4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/214312 Reviewed-by: Nate Bosch <nbosch@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Alexander Aprelev <aam@google.com>
1 parent ead8b7f commit 56403a0

22 files changed

+97
-98
lines changed

benchmarks/IsolateJson/dart/IsolateJson.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import 'dart:typed_data';
1010

1111
import 'package:benchmark_harness/benchmark_harness.dart' show BenchmarkBase;
1212

13-
import 'runtime/tests/vm/dart/export_sendAndExit_helper.dart' show sendAndExit;
14-
1513
class JsonDecodingBenchmark {
1614
JsonDecodingBenchmark(this.name,
1715
{required this.sample,
@@ -80,7 +78,7 @@ Future<Map> decodeJson(bool useSendAndExit, Uint8List encodedJson) async {
8078
Future<void> jsonDecodingIsolate(JsonDecodeRequest request) async {
8179
final result = json.decode(utf8.decode(request.encodedJson));
8280
if (request.useSendAndExit) {
83-
sendAndExit(request.sendPort, result);
81+
Isolate.exit(request.sendPort, result);
8482
} else {
8583
request.sendPort.send(result);
8684
}

benchmarks/IsolateJson/dart/runtime/tests/vm/dart/export_sendAndExit_helper.dart

Lines changed: 0 additions & 1 deletion
This file was deleted.

benchmarks/IsolateJson/dart2/IsolateJson.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import 'dart:typed_data';
1313
import 'package:benchmark_harness/benchmark_harness.dart' show BenchmarkBase;
1414
import 'package:meta/meta.dart';
1515

16-
import 'runtime/tests/vm/dart/export_sendAndExit_helper.dart' show sendAndExit;
17-
1816
class JsonDecodingBenchmark {
1917
JsonDecodingBenchmark(this.name,
2018
{@required this.sample,
@@ -83,7 +81,7 @@ Future<Map> decodeJson(bool useSendAndExit, Uint8List encodedJson) async {
8381
Future<void> jsonDecodingIsolate(JsonDecodeRequest request) async {
8482
final result = json.decode(utf8.decode(request.encodedJson));
8583
if (request.useSendAndExit) {
86-
sendAndExit(request.sendPort, result);
84+
Isolate.exit(request.sendPort, result);
8785
} else {
8886
request.sendPort.send(result);
8987
}

benchmarks/IsolateJson/dart2/runtime/tests/vm/dart/export_sendAndExit_helper.dart

Lines changed: 0 additions & 1 deletion
This file was deleted.

runtime/lib/isolate.cc

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -272,36 +272,37 @@ static ObjectPtr ValidateMessageObject(Zone* zone,
272272
return obj.ptr();
273273
}
274274

275-
DEFINE_NATIVE_ENTRY(SendPortImpl_sendAndExitInternal_, 0, 2) {
276-
GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
277-
if (!PortMap::IsReceiverInThisIsolateGroup(port.Id(), isolate->group())) {
278-
const auto& error =
279-
String::Handle(String::New("sendAndExit is only supported across "
280-
"isolates spawned via spawnFunction."));
281-
Exceptions::ThrowArgumentError(error);
282-
UNREACHABLE();
283-
}
284-
285-
GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
275+
DEFINE_NATIVE_ENTRY(Isolate_exit_, 0, 2) {
276+
GET_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
277+
if (!port.IsNull()) {
278+
GET_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
279+
if (!PortMap::IsReceiverInThisIsolateGroup(port.Id(), isolate->group())) {
280+
const auto& error =
281+
String::Handle(String::New("exit with final message is only allowed "
282+
"for isolates in one isolate group."));
283+
Exceptions::ThrowArgumentError(error);
284+
UNREACHABLE();
285+
}
286286

287-
Object& validated_result = Object::Handle(zone);
288-
const Object& msg_obj = Object::Handle(zone, obj.ptr());
289-
validated_result = ValidateMessageObject(zone, isolate, msg_obj);
290-
// msg_array = [
291-
// <message>,
292-
// <collection-lib-objects-to-rehash>,
293-
// <core-lib-objects-to-rehash>,
294-
// ]
295-
const Array& msg_array = Array::Handle(zone, Array::New(3));
296-
msg_array.SetAt(0, msg_obj);
297-
if (validated_result.IsUnhandledException()) {
298-
Exceptions::PropagateError(Error::Cast(validated_result));
299-
UNREACHABLE();
287+
Object& validated_result = Object::Handle(zone);
288+
const Object& msg_obj = Object::Handle(zone, obj.ptr());
289+
validated_result = ValidateMessageObject(zone, isolate, msg_obj);
290+
// msg_array = [
291+
// <message>,
292+
// <collection-lib-objects-to-rehash>,
293+
// <core-lib-objects-to-rehash>,
294+
// ]
295+
const Array& msg_array = Array::Handle(zone, Array::New(3));
296+
msg_array.SetAt(0, msg_obj);
297+
if (validated_result.IsUnhandledException()) {
298+
Exceptions::PropagateError(Error::Cast(validated_result));
299+
UNREACHABLE();
300+
}
301+
PersistentHandle* handle =
302+
isolate->group()->api_state()->AllocatePersistentHandle();
303+
handle->set_ptr(msg_array);
304+
isolate->bequeath(std::unique_ptr<Bequest>(new Bequest(handle, port.Id())));
300305
}
301-
PersistentHandle* handle =
302-
isolate->group()->api_state()->AllocatePersistentHandle();
303-
handle->set_ptr(msg_array);
304-
isolate->bequeath(std::unique_ptr<Bequest>(new Bequest(handle, port.Id())));
305306
Isolate::KillIfExists(isolate, Isolate::LibMsgId::kKillMsg);
306307
// Drain interrupts before running so any IMMEDIATE operations on the current
307308
// isolate happen synchronously.

runtime/tests/vm/dart/isolates/internal.dart

Lines changed: 0 additions & 14 deletions
This file was deleted.

runtime/tests/vm/dart/isolates/ring_gc_sendAndExit_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ main(args) async {
2424
final ring = await Ring.create(numIsolates);
2525

2626
// Let each node produce a tree, send it to it's neighbour and let it return
27-
// the one it received (via sendAndExit).
27+
// the one it received (via Isolate.exit).
2828
final results = await ring.runAndClose((int id) => Worker(id));
2929
Expect.equals(numIsolates, results.length);
3030

runtime/tests/vm/dart/isolates/test_utils.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import 'dart:async';
66
import 'dart:io';
77
import 'dart:isolate';
88

9-
import 'internal.dart';
10-
119
export '../../../../../benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart'
1210
show fibonacciRecursive;
1311

@@ -102,7 +100,7 @@ class Ring {
102100
case Command.kRunAndClose:
103101
final RingElement re = args[1];
104102
final SendPort nextNeighbor = args[2];
105-
port.sendAndExit(await re.run(nextNeighbor, siData));
103+
Isolate.exit(port, await re.run(nextNeighbor, siData));
106104
break;
107105
case Command.kClose:
108106
port.send('done');

runtime/tests/vm/dart/sendandexit_test.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
//
55
// VMOptions=--enable-isolate-groups
66
//
7-
// Validates functionality of sendAndExit.
7+
// Validates functionality of Isolate.exit().
88

9-
import 'dart:_internal' show sendAndExit;
109
import 'dart:async';
1110
import 'dart:isolate';
1211
import 'dart:nativewrappers';
@@ -27,7 +26,7 @@ spawnWorker(worker, data) async {
2726
verifyCantSendAnonymousClosure() async {
2827
final receivePort = ReceivePort();
2928
Expect.throws(
30-
() => sendAndExit(receivePort.sendPort, () {}),
29+
() => Isolate.exit(receivePort.sendPort, () {}),
3130
(e) =>
3231
e.toString() ==
3332
'Invalid argument: "Illegal argument in isolate message : '
@@ -40,7 +39,7 @@ class NativeWrapperClass extends NativeFieldWrapperClass1 {}
4039
verifyCantSendNative() async {
4140
final receivePort = ReceivePort();
4241
Expect.throws(
43-
() => sendAndExit(receivePort.sendPort, NativeWrapperClass()),
42+
() => Isolate.exit(receivePort.sendPort, NativeWrapperClass()),
4443
(e) => e.toString().startsWith('Invalid argument: '
4544
'"Illegal argument in isolate message : '
4645
'(object extends NativeWrapper'));
@@ -50,7 +49,7 @@ verifyCantSendNative() async {
5049
verifyCantSendReceivePort() async {
5150
final receivePort = ReceivePort();
5251
Expect.throws(
53-
() => sendAndExit(receivePort.sendPort, receivePort),
52+
() => Isolate.exit(receivePort.sendPort, receivePort),
5453
// closure is encountered first before we reach ReceivePort instance
5554
(e) => e.toString().startsWith(
5655
'Invalid argument: "Illegal argument in isolate message : '
@@ -62,7 +61,7 @@ verifyCantSendRegexp() async {
6261
final receivePort = ReceivePort();
6362
final regexp = RegExp("");
6463
Expect.throws(
65-
() => sendAndExit(receivePort.sendPort, regexp),
64+
() => Isolate.exit(receivePort.sendPort, regexp),
6665
(e) =>
6766
e.toString() ==
6867
'Invalid argument: '
@@ -73,7 +72,7 @@ verifyCantSendRegexp() async {
7372
add(a, b) => a + b;
7473

7574
worker(SendPort sendPort) async {
76-
sendAndExit(sendPort, add);
75+
Isolate.exit(sendPort, add);
7776
}
7877

7978
verifyCanSendStaticMethod() async {

runtime/tests/vm/dart_2/isolates/internal.dart

Lines changed: 0 additions & 16 deletions
This file was deleted.

runtime/tests/vm/dart_2/isolates/ring_gc_sendAndExit_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ main(args) async {
2626
final ring = await Ring.create(numIsolates);
2727

2828
// Let each node produce a tree, send it to it's neighbour and let it return
29-
// the one it received (via sendAndExit).
29+
// the one it received (via Isolate.exit()).
3030
final results = await ring.runAndClose((int id) => Worker(id));
3131
Expect.equals(numIsolates, results.length);
3232

runtime/tests/vm/dart_2/isolates/test_utils.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import 'dart:async';
88
import 'dart:io';
99
import 'dart:isolate';
1010

11-
import 'internal.dart';
12-
1311
export '../../../../../benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart'
1412
show fibonacciRecursive;
1513

@@ -104,7 +102,7 @@ class Ring {
104102
case Command.kRunAndClose:
105103
final RingElement re = args[1];
106104
final SendPort nextNeighbor = args[2];
107-
port.sendAndExit(await re.run(nextNeighbor, siData));
105+
Isolate.exit(port, await re.run(nextNeighbor, siData));
108106
break;
109107
case Command.kClose:
110108
port.send('done');

runtime/tests/vm/dart_2/sendandexit_test.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
//
55
// VMOptions=--enable-isolate-groups
66
//
7-
// Validates functionality of sendAndExit.
7+
// Validates functionality of Isolate.exit().
88

99
// @dart = 2.9
1010

11-
import 'dart:_internal' show sendAndExit;
1211
import 'dart:async';
1312
import 'dart:isolate';
1413
import 'dart:nativewrappers';
@@ -29,7 +28,7 @@ spawnWorker(worker, data) async {
2928
verifyCantSendAnonymousClosure() async {
3029
final receivePort = ReceivePort();
3130
Expect.throws(
32-
() => sendAndExit(receivePort.sendPort, () {}),
31+
() => Isolate.exit(receivePort.sendPort, () {}),
3332
(e) =>
3433
e.toString() ==
3534
'Invalid argument: "Illegal argument in isolate message : '
@@ -42,7 +41,7 @@ class NativeWrapperClass extends NativeFieldWrapperClass1 {}
4241
verifyCantSendNative() async {
4342
final receivePort = ReceivePort();
4443
Expect.throws(
45-
() => sendAndExit(receivePort.sendPort, NativeWrapperClass()),
44+
() => Isolate.exit(receivePort.sendPort, NativeWrapperClass()),
4645
(e) => e.toString().startsWith('Invalid argument: '
4746
'"Illegal argument in isolate message : '
4847
'(object extends NativeWrapper'));
@@ -52,7 +51,7 @@ verifyCantSendNative() async {
5251
verifyCantSendReceivePort() async {
5352
final receivePort = ReceivePort();
5453
Expect.throws(
55-
() => sendAndExit(receivePort.sendPort, receivePort),
54+
() => Isolate.exit(receivePort.sendPort, receivePort),
5655
// closure is encountered first before we reach ReceivePort instance
5756
(e) => e.toString().startsWith(
5857
'Invalid argument: "Illegal argument in isolate message : '
@@ -64,7 +63,7 @@ verifyCantSendRegexp() async {
6463
final receivePort = ReceivePort();
6564
final regexp = RegExp("");
6665
Expect.throws(
67-
() => sendAndExit(receivePort.sendPort, regexp),
66+
() => Isolate.exit(receivePort.sendPort, regexp),
6867
(e) =>
6968
e.toString() ==
7069
'Invalid argument: '
@@ -75,7 +74,7 @@ verifyCantSendRegexp() async {
7574
add(a, b) => a + b;
7675

7776
worker(SendPort sendPort) async {
78-
sendAndExit(sendPort, add);
77+
Isolate.exit(sendPort, add);
7978
}
8079

8180
verifyCanSendStaticMethod() async {

runtime/vm/bootstrap_natives.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ namespace dart {
6565
V(SendPortImpl_get_id, 1) \
6666
V(SendPortImpl_get_hashcode, 1) \
6767
V(SendPortImpl_sendInternal_, 2) \
68-
V(SendPortImpl_sendAndExitInternal_, 2) \
6968
V(Smi_bitNegate, 1) \
7069
V(Smi_bitLength, 1) \
7170
V(Mint_bitNegate, 1) \
@@ -316,12 +315,13 @@ namespace dart {
316315
V(Int32x4_setFlagZ, 2) \
317316
V(Int32x4_setFlagW, 2) \
318317
V(Int32x4_select, 3) \
319-
V(Isolate_spawnFunction, 10) \
320-
V(Isolate_spawnUri, 12) \
321-
V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) \
318+
V(Isolate_exit_, 2) \
322319
V(Isolate_getCurrentRootUriStr, 0) \
323-
V(Isolate_sendOOB, 2) \
324320
V(Isolate_getDebugName, 1) \
321+
V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) \
322+
V(Isolate_sendOOB, 2) \
323+
V(Isolate_spawnFunction, 10) \
324+
V(Isolate_spawnUri, 12) \
325325
V(GrowableList_allocate, 2) \
326326
V(GrowableList_getIndexed, 2) \
327327
V(GrowableList_setIndexed, 3) \

runtime/vm/dart_api_impl_test.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,10 @@ void Func1() {
756756
TEST_CASE(DartAPI_EnsureUnwindErrorHandled_WhenSendAndExit) {
757757
const char* kScriptChars = R"(
758758
import 'dart:isolate';
759-
import 'dart:_internal' show sendAndExit;
760759
761760
sendAndExitNow() {
762761
final receivePort = ReceivePort();
763-
sendAndExit(receivePort.sendPort, true);
762+
Isolate.exit(receivePort.sendPort, true);
764763
}
765764
766765
@pragma("vm:external-name", "Test_nativeFunc")

sdk/lib/_internal/js_dev_runtime/patch/isolate_patch.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ class Isolate {
7777

7878
@patch
7979
void removeErrorListener(SendPort port) => _unsupported();
80+
81+
@patch
82+
static Never exit([SendPort? finalMessagePort, Object? message]) =>
83+
_unsupported();
8084
}
8185

8286
/** Default factory for receive ports. */

sdk/lib/_internal/js_runtime/lib/isolate_patch.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ class Isolate {
106106
void removeErrorListener(SendPort port) {
107107
throw new UnsupportedError("Isolate.removeErrorListener");
108108
}
109+
110+
@patch
111+
static Never exit([SendPort? finalMessagePort, Object? message]) {
112+
throw new UnsupportedError("Isolate.exit");
113+
}
109114
}
110115

111116
@patch

sdk/lib/_internal/vm/lib/internal_patch.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,6 @@ external void reachabilityFence(Object object);
178178
@pragma("vm:external-name", "Internal_nativeEffect")
179179
external void _nativeEffect(Object object);
180180

181-
@pragma("vm:external-name", "SendPortImpl_sendAndExitInternal_")
182-
external void sendAndExit(SendPort sendPort, var message);
183-
184181
// Collection of functions which should only be used for testing purposes.
185182
abstract class VMInternalsForTesting {
186183
// This function can be used by tests to enforce garbage collection.

sdk/lib/_internal/vm/lib/isolate_patch.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,13 @@ class Isolate {
645645

646646
@pragma("vm:external-name", "Isolate_getCurrentRootUriStr")
647647
external static String _getCurrentRootUriStr();
648+
649+
@pragma("vm:external-name", "Isolate_exit_")
650+
external static Never _exit(SendPort? finalMessagePort, Object? message);
651+
652+
static Never exit([SendPort? finalMessagePort, Object? message]) {
653+
_exit(finalMessagePort, message);
654+
}
648655
}
649656

650657
@patch

0 commit comments

Comments
 (0)