-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vm] Use multiple entrypoints to remove unnecessary checks on calls a…
…gainst "this". Test Plan: Behavioral correctness should be ensured by existing tests. Tests in vm/dart/entrypoints ensure that the unchecked entrypoint is used in cases where the optimization should trigger. Bug: #31798 Change-Id: I5b880b2dfa6343b4bb0a96ad23562facff73e41f Cq-Include-Trybots: luci.dart.try:vm-kernel-win-release-x64-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try Reviewed-on: https://dart-review.googlesource.com/69741 Commit-Queue: Samir Jindel <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
- Loading branch information
1 parent
c082761
commit dea7de2
Showing
34 changed files
with
623 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# VM-Specific Pragma Annotations | ||
|
||
## Pragmas for general use | ||
|
||
These pragmas are part of the VM's API and are safe for use in external code. | ||
|
||
- **vm:entry-point** | ||
|
||
[Defining entry-points into Dart code for an embedder or native methods] | ||
(file://../vm/compiler/aot/entry_points_pragma.md) | ||
|
||
## Pragmas for internal testing | ||
|
||
These pragmas are used for inspecting or modifying internal VM state and should be used exclusively by SDK tests. They must be enabled with the `--enable-testing-pragmas` flag. The names of these pragmas are prefixed with "testing". Additionally, they are categorized into "safe" and "unsafe" forms: "safe" pragmas should not affect the behavior of the program and can be safely added anywhere. "unsafe" pragmas may change the code's behavior or may cause the VM to crash if used improperly. | ||
|
||
- **vm:testing.unsafe.trace-entrypoints-fn** | ||
|
||
[Observing which flow-graph-level entry-point was used when a function was called] | ||
(file://../vm/compiler/frontend/entrypoints_pragma.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright (c) 2018, 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 "package:expect/expect.dart"; | ||
|
||
// We want to run each test with and without inlining of the target functions. | ||
// We accomplish this by using VM options in the yes-inlining variant to set the | ||
// "enable_inlining" constant variable to true. This maximizes code sharing | ||
// between the two variants, which are otherwise identical. | ||
const String NeverInline = | ||
const bool.fromEnvironment("enable_inlining") ? "" : "NeverInline"; | ||
|
||
// All these tests can be run in test mode or in benchmark mode. In benchmark | ||
// mode, there is introspection is omitted and the tests runs for many more | ||
// iterations. | ||
const bool benchmarkMode = const bool.fromEnvironment("benchmark_mode"); | ||
|
||
int expectedEntryPoint = -1; | ||
int expectedTearoffEntryPoint = -1; | ||
|
||
// We check that this is true at the end of the test to ensure that the | ||
// introspection machinery is operational. | ||
bool validateRan = false; | ||
|
||
_validateHelper(int expected, int ep) { | ||
validateRan = true; | ||
if (ep < 0 || ep > 2) { | ||
Expect.fail("ERROR: invalid entry-point ($ep) passed by VM."); | ||
} | ||
if (expected < -1 || expected > 2) { | ||
Expect.fail("ERROR: invalid expected entry-point set ($expected)"); | ||
} | ||
if (expected == -1) return; | ||
Expect.equals(expected, ep); | ||
} | ||
|
||
void _validateFn(String _, int ep) => _validateHelper(expectedEntryPoint, ep); | ||
|
||
// Invocation of tearoffs go through a tearoff wrapper. We want to independently | ||
// test which entrypoint was used for the tearoff wrapper vs. which was used for | ||
// actual target. | ||
_validateTearoffFn(String name, int entryPoint) { | ||
_validateHelper( | ||
name.endsWith("#tearoff") | ||
? expectedTearoffEntryPoint | ||
: expectedEntryPoint, | ||
entryPoint); | ||
} | ||
|
||
const validate = benchmarkMode ? null : _validateFn; | ||
const validateTearoff = benchmarkMode ? null : _validateTearoffFn; |
65 changes: 65 additions & 0 deletions
65
runtime/tests/vm/dart/entrypoints/polymorphic_optional_this.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// Test that 'PolymorphicInstanceCall's against "this" go through the unchecked | ||
// entrypoint. The use of optional arguments here encourages prologue sharing | ||
// between the entrypoints. | ||
|
||
import "common.dart"; | ||
import "package:expect/expect.dart"; | ||
|
||
abstract class C<T> { | ||
@NeverInline | ||
void samir1(T x) { | ||
samir2(x, y: "hi"); | ||
} | ||
|
||
void samir2(T x, {String y}); | ||
} | ||
|
||
class D<T> extends C<T> { | ||
@NeverInline | ||
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validate) | ||
void samir2(T x, {String y}) { | ||
Expect.notEquals(x, -1); | ||
Expect.equals(y, "hi"); | ||
} | ||
} | ||
|
||
class E<T> extends C<T> { | ||
@NeverInline | ||
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validate) | ||
void samir2(T x, {String y}) { | ||
Expect.notEquals(x, -1); | ||
Expect.equals(y, "hi"); | ||
} | ||
} | ||
|
||
int j = 0; | ||
|
||
C getC() { | ||
if (j % 2 == 0) { | ||
++j; | ||
return new D<int>(); | ||
} else { | ||
++j; | ||
return new E<int>(); | ||
} | ||
} | ||
|
||
test(List<String> args) { | ||
// Warmup. | ||
expectedEntryPoint = -1; | ||
for (int i = 0; i < 100; ++i) { | ||
getC().samir1(i); | ||
} | ||
|
||
expectedEntryPoint = 2; | ||
const int iterations = benchmarkMode ? 100000000 : 100; | ||
for (int i = 0; i < iterations; ++i) { | ||
getC().samir1(i); | ||
} | ||
|
||
Expect.isTrue(validateRan); | ||
} |
9 changes: 9 additions & 0 deletions
9
runtime/tests/vm/dart/entrypoints/polymorphic_optional_this_inline_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true | ||
|
||
import "polymorphic_optional_this.dart"; | ||
|
||
main(args) => test(args); |
9 changes: 9 additions & 0 deletions
9
runtime/tests/vm/dart/entrypoints/polymorphic_optional_this_noinline_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 | ||
|
||
import "polymorphic_optional_this.dart"; | ||
|
||
main(args) => test(args); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// Test that 'PolymorphicInstanceCall's against "this" go through the unchecked | ||
// entrypoint. | ||
|
||
import "common.dart"; | ||
import "package:expect/expect.dart"; | ||
|
||
abstract class C<T> { | ||
@NeverInline | ||
void target1(T x) { | ||
target2(x); | ||
} | ||
|
||
void target2(T x); | ||
} | ||
|
||
class D<T> extends C<T> { | ||
@NeverInline | ||
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validate) | ||
void target2(T x) { | ||
Expect.notEquals(x, -1); | ||
} | ||
} | ||
|
||
class E<T> extends C<T> { | ||
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validate) | ||
@NeverInline | ||
void target2(T x) { | ||
Expect.notEquals(x, -1); | ||
} | ||
} | ||
|
||
int j = 0; | ||
|
||
C getC() { | ||
if (j % 2 == 0) { | ||
++j; | ||
return new D<int>(); | ||
} else { | ||
++j; | ||
return new E<int>(); | ||
} | ||
} | ||
|
||
test(List<String> args) { | ||
// Warmup. | ||
expectedEntryPoint = -1; | ||
for (int i = 0; i < 100; ++i) { | ||
getC().target1(0); | ||
} | ||
|
||
expectedEntryPoint = 1; | ||
const int iterations = benchmarkMode ? 200000000 : 100; | ||
for (int i = 0; i < iterations; ++i) { | ||
getC().target1(i); | ||
} | ||
|
||
// Once for D and once for E. | ||
expectedEntryPoint = 0; | ||
dynamic f = getC().target2; | ||
f(0); | ||
f = getC().target2; | ||
f(0); | ||
|
||
Expect.isTrue(validateRan); | ||
} |
9 changes: 9 additions & 0 deletions
9
runtime/tests/vm/dart/entrypoints/polymorphic_this_inline_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true | ||
|
||
import "polymorphic_this.dart"; | ||
|
||
main(args) => test(args); |
9 changes: 9 additions & 0 deletions
9
runtime/tests/vm/dart/entrypoints/polymorphic_this_noinline_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 | ||
|
||
import "polymorphic_this.dart"; | ||
|
||
main(args) => test(args); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// Test that 'StaticCall's against "this" go through the unchecked entry-point. | ||
|
||
import "common.dart"; | ||
import "package:expect/expect.dart"; | ||
|
||
class C<T> { | ||
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validate) | ||
@NeverInline | ||
void target2(T x) { | ||
Expect.notEquals(x, -1); | ||
} | ||
|
||
@NeverInline | ||
void target1(T x) { | ||
target2(x); | ||
} | ||
} | ||
|
||
test(List<String> args) { | ||
// Make sure the precise runtime-type of C is not known below. | ||
C c = args.length == 0 ? C<int>() : C<String>(); | ||
|
||
// Warmup. | ||
expectedEntryPoint = -1; | ||
for (int i = 0; i < 100; ++i) { | ||
c.target1(i); | ||
} | ||
|
||
expectedEntryPoint = 1; | ||
const int iterations = benchmarkMode ? 400000000 : 100; | ||
for (int i = 0; i < iterations; ++i) { | ||
c.target1(i); | ||
} | ||
|
||
expectedEntryPoint = 0; | ||
dynamic f = c.target2; | ||
f(0); | ||
|
||
Expect.isTrue(validateRan); | ||
} |
9 changes: 9 additions & 0 deletions
9
runtime/tests/vm/dart/entrypoints/static_this_inline_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true | ||
|
||
import "static_this.dart"; | ||
|
||
main(args) => test(args); |
9 changes: 9 additions & 0 deletions
9
runtime/tests/vm/dart/entrypoints/static_this_noinline_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2016, 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. | ||
|
||
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 | ||
|
||
import "static_this.dart"; | ||
|
||
main(args) => test(args); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.