Skip to content

Commit c854870

Browse files
mralephCommit Queue
authored andcommitted
[vm/io] Reduce baseline overhead in async IO
Instead of closing the IO service response port simply mark it as inactive when no requests are in flight. Creating receive ports in non-PRODUCT mode collects a stack trace which is very expensive. TEST=ci Change-Id: I6609688d6977e4401570578e19362af75ae57390 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406960 Commit-Queue: Slava Egorov <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 58fd1bd commit c854870

File tree

1 file changed

+20
-25
lines changed

1 file changed

+20
-25
lines changed

sdk/lib/_internal/vm/bin/io_service_patch.dart

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ external SendPort _newServicePort();
1111
class _IOService {
1212
static final SendPort _port = _newServicePort();
1313

14-
static RawReceivePort? _receivePort;
15-
static late SendPort _replyToPort;
14+
static final RawReceivePort _receivePort = RawReceivePort((
15+
List<Object?> data,
16+
) {
17+
assert(data.length == 2);
18+
_forwardResponse(data[0] as int, data[1]);
19+
}, 'IO Service');
1620
static HashMap<int, Completer> _messageMap = new HashMap<int, Completer>();
1721
static int _id = 0;
1822

@@ -24,38 +28,29 @@ class _IOService {
2428
} while (_messageMap.containsKey(id));
2529
final Completer completer = new Completer();
2630
try {
27-
_ensureInitialize();
31+
if (_messageMap.isEmpty) {
32+
// This is the first outgoing request after being in an idle state,
33+
// make sure to mark [_receivePort] alive.
34+
_receivePort.keepIsolateAlive = true;
35+
}
2836
_messageMap[id] = completer;
29-
_port.send(<dynamic>[id, _replyToPort, request, data]);
37+
_port.send(<dynamic>[id, _receivePort.sendPort, request, data]);
3038
} catch (error) {
31-
_messageMap.remove(id)!.complete(error);
32-
if (_messageMap.length == 0) {
33-
_finalize();
34-
}
39+
_forwardResponse(id, error);
3540
}
3641
return completer.future;
3742
}
3843

39-
static void _ensureInitialize() {
40-
if (_receivePort == null) {
41-
_receivePort = new RawReceivePort(null, 'IO Service');
42-
_replyToPort = _receivePort!.sendPort;
43-
_receivePort!.handler = (List<Object?> data) {
44-
assert(data.length == 2);
45-
_messageMap.remove(data[0])!.complete(data[1]);
46-
if (_messageMap.length == 0) {
47-
_finalize();
48-
}
49-
};
44+
static void _forwardResponse(int id, Object? response) {
45+
_messageMap.remove(id)!.complete(response);
46+
if (_messageMap.isEmpty) {
47+
// Last pending response received. We are entering idle state so
48+
// mark _receivePort inactive.
49+
_id = 0;
50+
_receivePort.keepIsolateAlive = false;
5051
}
5152
}
5253

53-
static void _finalize() {
54-
_id = 0;
55-
_receivePort!.close();
56-
_receivePort = null;
57-
}
58-
5954
static int _getNextId() {
6055
if (_id == 0x7FFFFFFF) _id = 0;
6156
return _id++;

0 commit comments

Comments
 (0)