Skip to content

Commit 4d95ec1

Browse files
sjindel-googlecommit-bot@chromium.org
authored andcommitted
[vm] Enable multiple entry-points for unoptimized calls.
This also makes the entrypoints tests less sensitive to the order in which functions are optimized and removes flaky checks. Fixes #37144. Fixes #39447. Change-Id: I5ba23c74769ddb8415e2b635caefc798c2b70500 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109704 Commit-Queue: Samir Jindel <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 659b32f commit 4d95ec1

24 files changed

+198
-221
lines changed

runtime/tests/vm/dart/entrypoints/aot/static_this_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
//
5-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
5+
// VMOptions=--enable-testing-pragmas -Denable_inlining=true
66

77
import '../static_this.dart';
88

runtime/tests/vm/dart/entrypoints/aot/super_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
//
5-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
5+
// VMOptions=--enable-testing-pragmas -Denable_inlining=true
66

77
import "../super.dart";
88

runtime/tests/vm/dart/entrypoints/common.dart

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,41 +23,53 @@ const pragma AlwaysInline = const bool.fromEnvironment("enable_inlining")
2323
// iterations.
2424
const bool benchmarkMode = const bool.fromEnvironment("benchmark_mode");
2525

26-
int expectedEntryPoint = -1;
27-
int expectedTearoffEntryPoint = -1;
26+
class TargetCalls {
27+
int checked = 0;
28+
int unchecked = 0;
2829

29-
// We check that this is true at the end of the test to ensure that the
30-
// introspection machinery is operational.
31-
bool validateRan = false;
30+
// Leave a little room for some cases which always use the checked entry, like
31+
// lazy compile stub or interpreter warm-up.
32+
static const int wiggle = 10;
33+
34+
void expectChecked(int iterations) {
35+
print("$checked, $unchecked");
36+
Expect.isTrue(checked >= iterations - wiggle && unchecked == 0);
37+
}
38+
39+
void expectUnchecked(int iterations) {
40+
print("$checked, $unchecked");
41+
Expect.isTrue(checked <= wiggle && unchecked >= iterations - wiggle);
42+
}
43+
}
44+
45+
TargetCalls entryPoint = TargetCalls();
46+
TargetCalls tearoffEntryPoint = TargetCalls();
47+
48+
_validateHelper(int ep, TargetCalls calls) {
49+
calls ??= entryPoint;
3250

33-
_validateHelper(int expected, int ep) {
34-
validateRan = true;
3551
if (ep < 0 || ep > 2) {
3652
Expect.fail("ERROR: invalid entry-point ($ep) passed by VM.");
3753
}
38-
if (expected < -1 || expected > 2) {
39-
Expect.fail("ERROR: invalid expected entry-point set ($expected)");
54+
if (ep == 0) {
55+
calls.checked++;
56+
} else {
57+
calls.unchecked++;
4058
}
41-
if (expected == -1) return;
42-
Expect.equals(expected, ep);
4359
}
4460

45-
void _validateFn(String _, int ep) => _validateHelper(expectedEntryPoint, ep);
61+
void _validateFn(String _, int ep) => _validateHelper(ep, null);
4662

4763
// Invocation of tearoffs go through a tearoff wrapper. We want to independently
4864
// test which entrypoint was used for the tearoff wrapper vs. which was used for
4965
// actual target.
50-
_validateTearoffFn(String name, int entryPoint) {
66+
_validateTearoffFn(String name, int ep) {
5167
_validateHelper(
52-
name.endsWith("#tearoff")
53-
? expectedTearoffEntryPoint
54-
: expectedEntryPoint,
55-
entryPoint);
68+
ep, name.endsWith("#tearoff") ? tearoffEntryPoint : entryPoint);
5669
}
5770

5871
@pragma("vm:entry-point", "get")
5972
const validate = benchmarkMode ? null : _validateFn;
73+
6074
@pragma("vm:entry-point", "get")
6175
const validateTearoff = benchmarkMode ? null : _validateTearoffFn;
62-
63-
void bumpUsageCounter() {}

runtime/tests/vm/dart/entrypoints/jit/polymorphic_optional_this_test.dart

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
//
5-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
6-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
5+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true --compilation-counter-threshold=1
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 --compilation-counter-threshold=1
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1 --compilation-counter-threshold=1
78

89
// Test that 'PolymorphicInstanceCall's against "this" go through the unchecked
910
// entrypoint. The use of optional arguments here encourages prologue sharing
@@ -15,14 +16,6 @@ import "package:expect/expect.dart";
1516
abstract class C<T> {
1617
@NeverInline
1718
void samir1(T x) {
18-
// Make sure this method gets optimized before main.
19-
// Otherwise it might get inlined into warm-up loop, and subsequent
20-
// loop will call an unoptimized version (which is not guaranteed to
21-
// dispatch to unchecked entry point).
22-
bumpUsageCounter();
23-
bumpUsageCounter();
24-
bumpUsageCounter();
25-
2619
samir2(x, y: "hi");
2720
}
2821

@@ -62,17 +55,10 @@ C getC() {
6255
}
6356

6457
main(List<String> args) {
65-
// Warmup.
66-
expectedEntryPoint = -1;
67-
for (int i = 0; i < 100; ++i) {
68-
getC().samir1(i);
69-
}
70-
71-
expectedEntryPoint = 2;
7258
const int iterations = benchmarkMode ? 100000000 : 100;
7359
for (int i = 0; i < iterations; ++i) {
7460
getC().samir1(i);
7561
}
7662

77-
Expect.isTrue(validateRan);
63+
entryPoint.expectUnchecked(iterations);
7864
}

runtime/tests/vm/dart/entrypoints/jit/polymorphic_this_test.dart

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
//
5-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
6-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
5+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true --compilation-counter-threshold=1
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 --compilation-counter-threshold=1
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1 --compilation-counter-threshold=1
78

89
// Test that 'PolymorphicInstanceCall's against "this" go through the unchecked
910
// entrypoint.
@@ -14,14 +15,6 @@ import "package:expect/expect.dart";
1415
abstract class C<T> {
1516
@NeverInline
1617
void target1(T x) {
17-
// Make sure this method gets optimized before main.
18-
// Otherwise it might get inlined into warm-up loop, and subsequent
19-
// loop will call an unoptimized version (which is not guaranteed to
20-
// dispatch to unchecked entry point).
21-
bumpUsageCounter();
22-
bumpUsageCounter();
23-
bumpUsageCounter();
24-
2518
target2(x);
2619
}
2720

@@ -57,24 +50,10 @@ C getC() {
5750
}
5851

5952
main(List<String> args) {
60-
// Warmup.
61-
expectedEntryPoint = -1;
62-
for (int i = 0; i < 100; ++i) {
63-
getC().target1(0);
64-
}
65-
66-
expectedEntryPoint = 1;
6753
const int iterations = benchmarkMode ? 200000000 : 100;
6854
for (int i = 0; i < iterations; ++i) {
6955
getC().target1(i);
7056
}
7157

72-
// Once for D and once for E.
73-
expectedEntryPoint = 0;
74-
dynamic x = getC();
75-
x.target2(0);
76-
x = getC();
77-
x.target2(0);
78-
79-
Expect.isTrue(validateRan);
58+
entryPoint.expectUnchecked(iterations);
8059
}

runtime/tests/vm/dart/entrypoints/jit/static_this_test.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
//
5-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5
6-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
5+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 --compilation-counter-threshold=5
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true --compilation-counter-threshold=5
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1 --compilation-counter-threshold=5
78

89
import '../static_this.dart';
910

runtime/tests/vm/dart/entrypoints/jit/super_test.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
//
5-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
6-
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5
5+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true --compilation-counter-threshold=5
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 --compilation-counter-threshold=5
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1 --compilation-counter-threshold=5
78

89
import "../super.dart";
910

runtime/tests/vm/dart/entrypoints/static_this.dart

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import "package:expect/expect.dart";
99

1010
class C<T> {
1111
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validate)
12+
@pragma("vm:entry-point")
1213
@NeverInline
1314
@AlwaysInline
1415
void target2(T x) {
@@ -17,14 +18,6 @@ class C<T> {
1718

1819
@NeverInline
1920
void target1(T x) {
20-
// Make sure this method gets optimized before main.
21-
// Otherwise it might get inlined into warm-up loop, and subsequent
22-
// loop will call an unoptimized version (which is not guaranteed to
23-
// dispatch to unchecked entry point).
24-
bumpUsageCounter();
25-
bumpUsageCounter();
26-
bumpUsageCounter();
27-
2821
target2(x);
2922
}
3023
}
@@ -33,21 +26,10 @@ test(List<String> args) {
3326
// Make sure the precise runtime-type of C is not known below.
3427
C c = args.length == 0 ? C<int>() : C<String>();
3528

36-
// Warmup.
37-
expectedEntryPoint = -1;
38-
for (int i = 0; i < 100; ++i) {
39-
c.target1(i);
40-
}
41-
42-
expectedEntryPoint = 1;
4329
const int iterations = benchmarkMode ? 400000000 : 100;
4430
for (int i = 0; i < iterations; ++i) {
4531
c.target1(i);
4632
}
4733

48-
expectedEntryPoint = 0;
49-
dynamic x = c;
50-
x.target2(0);
51-
52-
Expect.isTrue(validateRan);
34+
entryPoint.expectUnchecked(iterations);
5335
}

runtime/tests/vm/dart/entrypoints/super.dart

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,13 @@ class C<T> {
1919
class D<T> extends C<T> {
2020
@NeverInline
2121
void target1(T x) {
22-
// Make sure this method gets optimized before main.
23-
// Otherwise it might get inlined into warm-up loop, and subsequent
24-
// loop will call an unoptimized version (which is not guaranteed to
25-
// dispatch to unchecked entry point).
26-
bumpUsageCounter();
27-
bumpUsageCounter();
28-
bumpUsageCounter();
29-
3022
super.target1(x);
3123
}
3224
}
3325

3426
class E<T> extends C<T> {
3527
@NeverInline
3628
void target1(T x) {
37-
// Make sure this method gets optimized before main.
38-
// Otherwise it might get inlined into warm-up loop, and subsequent
39-
// loop will call an unoptimized version (which is not guaranteed to
40-
// dispatch to unchecked entry point).
41-
bumpUsageCounter();
42-
bumpUsageCounter();
43-
bumpUsageCounter();
44-
4529
super.target1(x);
4630
}
4731
}
@@ -60,26 +44,16 @@ C getC() {
6044
}
6145
}
6246

63-
// This works around issues with OSR not totally respecting the optimization
64-
// counter threshold.
65-
void testOneC(C x, int i) => x.target1(i);
66-
6747
test(List<String> args) {
6848
// Make sure the check on target1.x is not completely eliminated.
6949
if (args.length > 0) {
7050
(C<int>() as C<num>).target1(1.0);
7151
}
7252

73-
expectedEntryPoint = -1;
74-
for (int i = 0; i < 100; ++i) {
75-
testOneC(getC(), i);
76-
}
77-
78-
expectedEntryPoint = 1;
7953
const int iterations = benchmarkMode ? 200000000 : 100;
8054
for (int i = 0; i < iterations; ++i) {
81-
testOneC(getC(), i);
55+
getC().target1(i);
8256
}
8357

84-
Expect.isTrue(validateRan);
58+
entryPoint.expectUnchecked(iterations);
8559
}

runtime/tests/vm/dart/entrypoints/tearoff_prologue_test.dart

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// No type checks are removed here, but we can skip the argument count check.
66
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
77
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
8+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
89

910
import "package:expect/expect.dart";
1011
import "common.dart";
@@ -20,23 +21,19 @@ class C<T> {
2021
}
2122
}
2223

24+
void run(void Function(int) test, int i) {
25+
test(i);
26+
}
27+
2328
main(List<String> args) {
2429
var c = new C<int>();
2530
var f = c.samir1;
2631

27-
// Warmup.
28-
expectedEntryPoint = -1;
29-
expectedTearoffEntryPoint = -1;
30-
for (int i = 0; i < 100; ++i) {
31-
f(i);
32-
}
33-
34-
expectedEntryPoint = 0;
35-
expectedTearoffEntryPoint = 1;
36-
int iterations = benchmarkMode ? 100000000 : 100;
32+
const int iterations = benchmarkMode ? 100000000 : 100;
3733
for (int i = 0; i < iterations; ++i) {
38-
f(i);
34+
run(f, i);
3935
}
4036

41-
Expect.isTrue(validateRan);
37+
entryPoint.expectChecked(iterations);
38+
tearoffEntryPoint.expectUnchecked(iterations);
4239
}

runtime/tests/vm/dart/entrypoints/tearoff_test.dart

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//
55
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
66
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
78

89
// Test that typed calls against tearoffs go into the unchecked entrypoint.
910

@@ -20,22 +21,18 @@ class C<T> {
2021
}
2122
}
2223

24+
void run(void Function(int, String) fn, int i) {
25+
fn(i, "foo");
26+
}
27+
2328
main(List<String> args) {
2429
var f = (new C<int>()).target1;
2530

26-
// Warmup.
27-
expectedEntryPoint = -1;
28-
expectedTearoffEntryPoint = -1;
29-
for (int i = 0; i < 100; ++i) {
30-
f(i, "foo");
31-
}
32-
33-
expectedEntryPoint = 0;
34-
expectedTearoffEntryPoint = 1;
3531
const int iterations = benchmarkMode ? 100000000 : 100;
3632
for (int i = 0; i < iterations; ++i) {
37-
f(i, "foo");
33+
run(f, i);
3834
}
3935

40-
Expect.isTrue(validateRan);
36+
entryPoint.expectChecked(iterations);
37+
tearoffEntryPoint.expectUnchecked(iterations);
4138
}

0 commit comments

Comments
 (0)