Skip to content

Commit 058265f

Browse files
alexmarkovCommit Bot
authored and
Commit Bot
committed
Reland "[vm] More efficient 'await' of not Future and completed _Future"
This is a reland of commit 6b3d175 Fixes b/235734143 TEST=runtime/tests/vm/dart/await_in_custom_zone_test.dart Original change's description: > [vm] More efficient 'await' of not Future and completed _Future > > When awaiting a value which is not a Future or a completed > built-in _Future, 'await' implementation can bypass heavyweight > _Future/_FutureListener machinery and schedule micro-tasks directly. > > Benchmarks: > JIT, x64: > AsyncLiveVars.* +46-54% (bigger is better) > Calls.AwaitAsyncCall -46% (less is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -46% > Calls.AwaitAsyncCallClosureTargetPolymorphic -45% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -45% > Calls.AwaitFutureOrCall -60% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -60% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -59% > > JIT, ia32: > AsyncLiveVars.* +43-52% (bigger is better) > Calls.AwaitAsyncCall -42% (less is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -42% > Calls.AwaitAsyncCallClosureTargetPolymorphic -41% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -39% > Calls.AwaitFutureOrCall -55% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -54% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -53% > > JIT, arm: > AsyncLiveVars.* +64-71% (bigger is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -51% (less is better) > Calls.AwaitAsyncCallClosureTargetPolymorphic -47% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -48% > Calls.AwaitFutureOrCall -64% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -64% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -59% > > JIT, arm64: > AsyncLiveVars.* +65-78% (bigger is better) > Calls.AwaitAsyncCall -51% (less is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -51% > Calls.AwaitAsyncCallClosureTargetPolymorphic -50% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -49% > Calls.AwaitFutureOrCall -69% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -68% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -67% > > AOT, x64: > AsyncLiveVars.* +55-61% (bigger is better) > Calls.AwaitAsyncCall -47% (less is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -46% > Calls.AwaitAsyncCallClosureTargetPolymorphic -47% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -46% > Calls.AwaitFutureOrCall -59% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -59% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -58% > > AOT, arm: > AsyncLiveVars.* 54-66% (bigger is better) > Calls.AwaitAsyncCall -46-51% (less is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -46-50% > Calls.AwaitAsyncCallClosureTargetPolymorphic -46-52% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -45-50% > Calls.AwaitFutureOrCall -63-68% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -63-66% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -63-67% > > AOT, arm64: > AsyncLiveVars.* +53-66% (bigger is better) > Calls.AwaitAsyncCall -50-51% (less is better) > Calls.AwaitAsyncCallInstanceTargetPolymorphic -50% > Calls.AwaitAsyncCallClosureTargetPolymorphic -50-51% > Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits -49-50% > Calls.AwaitFutureOrCall -66-68% > Calls.AwaitFutureOrCallInstanceTargetPolymorphic -66-68% > Calls.AwaitFutureOrCallClosureTargetPolymorphic -63-67% > > TEST=ci > Issue: #48378 > > Change-Id: I65e3702fcd816ee3fee876ff442b9887c035b1ec > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243102 > Reviewed-by: Lasse Nielsen <[email protected]> > Commit-Queue: Alexander Markov <[email protected]> Change-Id: I245984ace1c768fdcba58dfdd6aa46e52126be4e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248442 Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Lasse Nielsen <[email protected]> Reviewed-by: Slava Egorov <[email protected]>
1 parent 07f7e45 commit 058265f

File tree

7 files changed

+472
-20
lines changed

7 files changed

+472
-20
lines changed

pkg/vm_service/test/get_stack_test.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ final tests = <IsolateTest>[
9595
(VmService service, IsolateRef isolateRef) async {
9696
final result = await service.getStack(isolateRef.id!);
9797

98-
expect(result.frames, hasLength(10));
98+
expect(result.frames, hasLength(6));
9999
expect(result.asyncCausalFrames, hasLength(26));
100100
expect(result.awaiterFrames, hasLength(13));
101101

@@ -105,10 +105,6 @@ final tests = <IsolateTest>[
105105
[equals('Regular'), anything], // Internal mech. ..
106106
[equals('Regular'), anything],
107107
[equals('Regular'), anything],
108-
[equals('Regular'), anything],
109-
[equals('Regular'), anything],
110-
[equals('Regular'), anything],
111-
[equals('Regular'), anything],
112108
[equals('Regular'), endsWith(' _RawReceivePortImpl._handleMessage')],
113109
]);
114110

runtime/observatory/tests/service/get_stack_limit_rpc_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ var tests = <IsolateTest>[
5151
var frames = stack['frames'];
5252
var asyncFrames = stack['asyncCausalFrames'];
5353
var awaiterFrames = stack['awaiterFrames'];
54-
expect(frames.length, greaterThanOrEqualTo(20));
54+
expect(frames.length, greaterThanOrEqualTo(12));
5555
expect(asyncFrames.length, greaterThan(frames.length));
5656
expect(awaiterFrames.length, greaterThan(frames.length));
5757
expect(stack['truncated'], false);

runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ var tests = <IsolateTest>[
5151
var frames = stack['frames'];
5252
var asyncFrames = stack['asyncCausalFrames'];
5353
var awaiterFrames = stack['awaiterFrames'];
54-
expect(frames.length, greaterThanOrEqualTo(20));
54+
expect(frames.length, greaterThanOrEqualTo(12));
5555
expect(asyncFrames.length, greaterThan(frames.length));
5656
expect(awaiterFrames.length, greaterThan(frames.length));
5757
expect(stack['truncated'], false);
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// This test verifies that 'await' implementation calls Zone callbacks from
6+
// correct Zones.
7+
8+
import 'dart:async';
9+
10+
import 'package:expect/expect.dart';
11+
12+
List<String> log = [];
13+
14+
class TestZone {
15+
final String name;
16+
TestZone(this.name);
17+
18+
static T run<T>(String name, T Function() callback) {
19+
final tz = TestZone(name);
20+
final zone = Zone.current.fork(
21+
specification: ZoneSpecification(
22+
runUnary: tz.runUnary,
23+
runBinary: tz.runBinary,
24+
registerUnaryCallback: tz.registerUnaryCallback,
25+
registerBinaryCallback: tz.registerBinaryCallback,
26+
scheduleMicrotask: tz.scheduleMicrotask));
27+
return zone.run(callback);
28+
}
29+
30+
R runUnary<R, T>(
31+
Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f, T arg) {
32+
log.add('$name.runUnary');
33+
return parent.runUnary(zone, f, arg);
34+
}
35+
36+
R runBinary<R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone,
37+
R Function(T1 arg1, T2 arg2) f, T1 arg1, T2 arg2) {
38+
log.add('$name.runBinary');
39+
return parent.runBinary(zone, f, arg1, arg2);
40+
}
41+
42+
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(
43+
Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f) {
44+
log.add('$name.registerUnaryCallback');
45+
return parent.registerUnaryCallback(zone, (T arg) {
46+
log.add('$name.unaryCallback');
47+
return f(arg);
48+
});
49+
}
50+
51+
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(Zone self,
52+
ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f) {
53+
log.add('$name.registerBinaryCallback');
54+
return parent.registerBinaryCallback(zone, (T1 arg1, T2 arg2) {
55+
log.add('$name.binaryCallback');
56+
return f(arg1, arg2);
57+
});
58+
}
59+
60+
void scheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, void f()) {
61+
log.add('$name.scheduleMicrotask');
62+
parent.scheduleMicrotask(zone, f);
63+
}
64+
}
65+
66+
Future<void> foo() async {
67+
log.add('--- step 3');
68+
}
69+
70+
Future<void> baz() async {
71+
log.add('--- step 8');
72+
}
73+
74+
Future<void> bar() async {
75+
log.add('--- step 6');
76+
77+
Future f = TestZone.run('Z3', () {
78+
log.add('--- step 7');
79+
return baz();
80+
});
81+
82+
log.add('--- step 9');
83+
await TestZone.run('Z4', () async {
84+
log.add('--- step 10');
85+
await f;
86+
log.add('--- step 13');
87+
});
88+
log.add('--- step 14');
89+
}
90+
91+
main() async {
92+
log.add('--- start');
93+
await TestZone.run('Z1', () async {
94+
log.add('--- step 1');
95+
await null;
96+
log.add('--- step 2');
97+
await foo();
98+
99+
log.add('--- step 4');
100+
await TestZone.run('Z2', () async {
101+
log.add('--- step 5');
102+
Future f = bar();
103+
104+
log.add('--- step 11');
105+
await TestZone.run('Z4', () async {
106+
log.add('--- step 12');
107+
await f;
108+
log.add('--- step 15');
109+
});
110+
log.add('--- step 16');
111+
});
112+
log.add('--- step 17');
113+
});
114+
log.add('--- end');
115+
116+
print('Actual log = [');
117+
for (int i = 0; i < log.length; ++i) {
118+
print(" /* $i */ '${log[i]}',");
119+
}
120+
print('];');
121+
122+
List<String> expectedLog = [
123+
/* 0 */ '--- start',
124+
/* 1 */ '--- step 1',
125+
/* 2 */ 'Z1.registerUnaryCallback',
126+
/* 3 */ 'Z1.registerBinaryCallback',
127+
/* 4 */ 'Z1.scheduleMicrotask',
128+
/* 5 */ 'Z1.runUnary',
129+
/* 6 */ 'Z1.unaryCallback',
130+
/* 7 */ '--- step 2',
131+
/* 8 */ '--- step 3',
132+
/* 9 */ 'Z1.scheduleMicrotask',
133+
/* 10 */ 'Z1.runUnary',
134+
/* 11 */ 'Z1.unaryCallback',
135+
/* 12 */ '--- step 4',
136+
/* 13 */ '--- step 5',
137+
/* 14 */ '--- step 6',
138+
/* 15 */ '--- step 7',
139+
/* 16 */ '--- step 8',
140+
/* 17 */ '--- step 9',
141+
/* 18 */ '--- step 10',
142+
/* 19 */ 'Z4.registerUnaryCallback',
143+
/* 20 */ 'Z2.registerUnaryCallback',
144+
/* 21 */ 'Z1.registerUnaryCallback',
145+
/* 22 */ 'Z4.registerBinaryCallback',
146+
/* 23 */ 'Z2.registerBinaryCallback',
147+
/* 24 */ 'Z1.registerBinaryCallback',
148+
/* 25 */ 'Z3.scheduleMicrotask',
149+
/* 26 */ 'Z2.scheduleMicrotask',
150+
/* 27 */ 'Z1.scheduleMicrotask',
151+
/* 28 */ 'Z2.registerUnaryCallback',
152+
/* 29 */ 'Z1.registerUnaryCallback',
153+
/* 30 */ 'Z2.registerBinaryCallback',
154+
/* 31 */ 'Z1.registerBinaryCallback',
155+
/* 32 */ '--- step 11',
156+
/* 33 */ '--- step 12',
157+
/* 34 */ 'Z4.registerUnaryCallback',
158+
/* 35 */ 'Z2.registerUnaryCallback',
159+
/* 36 */ 'Z1.registerUnaryCallback',
160+
/* 37 */ 'Z4.registerBinaryCallback',
161+
/* 38 */ 'Z2.registerBinaryCallback',
162+
/* 39 */ 'Z1.registerBinaryCallback',
163+
/* 40 */ 'Z2.registerUnaryCallback',
164+
/* 41 */ 'Z1.registerUnaryCallback',
165+
/* 42 */ 'Z2.registerBinaryCallback',
166+
/* 43 */ 'Z1.registerBinaryCallback',
167+
/* 44 */ 'Z4.runUnary',
168+
/* 45 */ 'Z2.runUnary',
169+
/* 46 */ 'Z1.runUnary',
170+
/* 47 */ 'Z1.unaryCallback',
171+
/* 48 */ 'Z2.unaryCallback',
172+
/* 49 */ 'Z4.unaryCallback',
173+
/* 50 */ '--- step 13',
174+
/* 51 */ 'Z2.runUnary',
175+
/* 52 */ 'Z1.runUnary',
176+
/* 53 */ 'Z1.unaryCallback',
177+
/* 54 */ 'Z2.unaryCallback',
178+
/* 55 */ '--- step 14',
179+
/* 56 */ 'Z4.runUnary',
180+
/* 57 */ 'Z2.runUnary',
181+
/* 58 */ 'Z1.runUnary',
182+
/* 59 */ 'Z1.unaryCallback',
183+
/* 60 */ 'Z2.unaryCallback',
184+
/* 61 */ 'Z4.unaryCallback',
185+
/* 62 */ '--- step 15',
186+
/* 63 */ 'Z2.runUnary',
187+
/* 64 */ 'Z1.runUnary',
188+
/* 65 */ 'Z1.unaryCallback',
189+
/* 66 */ 'Z2.unaryCallback',
190+
/* 67 */ '--- step 16',
191+
/* 68 */ 'Z1.runUnary',
192+
/* 69 */ 'Z1.unaryCallback',
193+
/* 70 */ '--- step 17',
194+
/* 71 */ '--- end',
195+
];
196+
Expect.listEquals(expectedLog, log);
197+
}

0 commit comments

Comments
 (0)