[vm/compiler] Implement new inlining pragmas.

This change introduces two new pragmas:

* `@pragma('vm:never-inline')`
* `@pragma('vm:prefer-inline')`

These replaces the old way of specifying AlwaysInline or NeverInline
annotations when the (now removed) --enable-inlining-annotations flag
was used.

Bug: https://github.com/dart-lang/sdk/issues/36571
Change-Id: I2495c72819d94e43cefc837d4eb454b7b3d4140c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99148
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Samir Jindel <sjindel@google.com>
This commit is contained in:
Teagan Strickland 2019-07-16 09:41:12 +00:00 committed by commit-bot@chromium.org
parent 1c4ad14fa3
commit 629f38cf87
55 changed files with 300 additions and 386 deletions

View file

@ -1,6 +1,31 @@
# @pragma annotations recognized by the compiler.
# Pragma annotations recognized by the compiler
## Annotations for return types and field types.
## Annotations for functions and methods
### Changing whether a function or method is inlined
The user can change whether the VM attempts to inline a given function or method
with the following pragmas.
#### Requesting a function be inlined
```dart
@pragma("vm:prefer-inline")
```
Here, the VM will inline the annotated function when possible. However, other
factors can prevent inlining and thus this pragma may not always be respected.
#### Requesting a function never be inlined
```dart
@pragma("vm:never-inline")
```
Here, the VM will not inline the annotated function. In this case, the pragma
is always respected.
## Annotations for return types and field types
The VM is not able to see across method calls (apart from inlining) and
therefore does not know anything about the return'ed values of calls, except for
@ -9,10 +34,10 @@ the interface type of the signature.
To improve this we have two types of additional information sources the VM
utilizes to gain knowledge about return types:
- inferred types (stored in kernel metadata): these are computed by global
transformations (e.g. TFA) and are only available in AOT mode
- inferred types (stored in kernel metadata): these are computed by global
transformations (e.g. TFA) and are only available in AOT mode
- @pragma annotations: these are recognized in JIT and AOT mode
- `@pragma` annotations: these are recognized in JIT and AOT mode
This return type information is mainly used in the VM's type propagator.
@ -20,22 +45,31 @@ Since those annotations side-step the normal type system, they are unsafe and we
therefore restrict those annotations to only have an affect inside dart:
libraries.
### @pragma("vm:exact-result-type", <type>) annotation
### Providing an exact result type
```dart
@pragma("vm:exact-result-type", <type>)
```
Tells the VM about the exact result type (i.e. the exact class-id) of a function
or a field load.
There are two limitations on this pragma:
0. The Dart object returned by the method at runtime must have **exactly** the type specified in the annotation (not a subtype).
- The Dart object returned by the method at runtime must have **exactly** the
type specified in the annotation (not a subtype).
1. The exact return type declared in the pragma must be a subtype of the interface type declared in the method signature.
Note that this restriction is not enforced automatically by the compiler.
- The exact return type declared in the pragma must be a subtype of the
interface type declared in the method signature.
**Note:** This limitation is not enforced automatically by the compiler.
If those limitations are violated, undefined behavior may result.
Note that since `null` is an instance of the `Null` type, which is a subtype of any other, exactness of the annotated result type implies that the result must be non-null.
Note that since `null` is an instance of the `Null` type, which is a subtype of
any other, exactness of the annotated result type implies that the result must
be non-null.
#### Syntax
#### Examples for exact result types
```dart
class A {}
@ -60,17 +94,21 @@ class C {
}
```
### @pragma("vm:non-nullable-result-type") annotation
### Declaring a result type non-nullable
```dart
@pragma("vm:non-nullable-result-type")
```
Tells the VM that the method/field cannot return `null`.
There is one limitation on this pragma:
0. The Dart object returned by the method at runtime **must not** return `null`.
- The Dart object returned by the method at runtime **must not** return `null`.
If this limitation is violated, undefined behavior may result.
#### Syntax
#### Examples for non-nullable result types
```dart
@pragma("vm:non-nullable-result-type")

View file

@ -7,6 +7,8 @@ These pragmas are part of the VM's API and are safe for use in external code.
| Pragma | Meaning |
| --- | --- |
| `vm:entry-point` | [Defining entry-points into Dart code for an embedder or native methods](compiler/aot/entry_point_pragma.md) |
| `vm:never-inline` | [Never inline a function or method](compiler/pragmas_recognized_by_compiler.md#requesting-a-function-never-be-inlined) |
| `vm:prefer-inline` | [Inline a function or method when possible](compiler/pragmas_recognized_by_compiler.md#requesting-a-function-be-inlined) |
## Pragmas for internal use
@ -14,7 +16,7 @@ These pragmas can cause unsound behavior if used incorrectly and therefore are o
| Pragma | Meaning |
| --- | --- |
| `vm:exact-result-type` | [Declaring an exact result type of a method](compiler/result_type_pragma.md) |
| `vm:exact-result-type` | [Declaring an exact result type of a method](compiler/pragmas_recognized_by_compiler.md#providing-an-exact-result-type) |
## Pragmas for internal testing

View file

@ -1,7 +1,6 @@
// 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.
// VMOptions=--no-background-compilation --enable-inlining-annotations
import 'dart:async';
import 'dart:developer';
@ -12,8 +11,6 @@ import 'package:unittest/unittest.dart';
import 'service_test_common.dart';
import 'test_helper.dart';
const String NeverInline = 'NeverInline';
class Base<T> {
String field;
@ -41,7 +38,7 @@ class ISub<T> implements Base<T> {
class Box<T> {
T value;
@NeverInline
@pragma('vm:never-inline')
void setValue(T value) {
this.value = value;
}

View file

@ -8,17 +8,14 @@ import 'package:unittest/unittest.dart';
import 'service_test_common.dart';
import 'test_helper.dart';
const alwaysInline = "AlwaysInline";
const noInline = "NeverInline";
int LINE_A = 34;
int LINE_B = 39;
int LINE_C = 42;
int LINE_D = 46;
int LINE_A = 31;
int LINE_B = 36;
int LINE_C = 39;
int LINE_D = 43;
int global = 0;
@noInline
@pragma('vm:never-inline')
b3(x) {
int sum = 0;
try {
@ -35,10 +32,10 @@ b3(x) {
return sum;
}
@alwaysInline
@pragma('vm:prefer-inline')
b2(x) => b3(x); // Line B
@alwaysInline
@pragma('vm:prefer-inline')
b1(x) => b2(x); // Line C
test() {
@ -79,7 +76,6 @@ var tests = <IsolateTest>[
main(args) => runIsolateTests(args, tests, testeeConcurrent: test, extraArgs: [
'--trace-rewind',
'--prune-dead-locals',
'--enable-inlining-annotations',
'--no-background-compilation',
'--optimization-counter-threshold=10'
]);

View file

@ -8,17 +8,14 @@ import 'package:unittest/unittest.dart';
import 'service_test_common.dart';
import 'test_helper.dart';
const alwaysInline = "AlwaysInline";
const noInline = "NeverInline";
int LINE_A = 34;
int LINE_B = 39;
int LINE_C = 42;
int LINE_D = 46;
int LINE_A = 31;
int LINE_B = 36;
int LINE_C = 39;
int LINE_D = 43;
int global = 0;
@noInline
@pragma('vm:never-inline')
b3(x) {
int sum = 0;
try {
@ -35,10 +32,10 @@ b3(x) {
return sum;
}
@alwaysInline
@pragma('vm:prefer-inline')
b2(x) => b3(x); // Line B
@alwaysInline
@pragma('vm:prefer-inline')
b1(x) => b2(x); // Line C
test() {
@ -151,7 +148,6 @@ var tests = <IsolateTest>[
main(args) => runIsolateTests(args, tests, testeeConcurrent: test, extraArgs: [
'--trace-rewind',
'--no-prune-dead-locals',
'--enable-inlining-annotations',
'--no-background-compilation',
'--optimization-counter-threshold=10'
]);

View file

@ -1,7 +1,7 @@
// 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.
// VMOptions=--no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=100
// VMOptions=--no-background-compilation --optimization-counter-threshold=100
// Verify that runtime correctly materializes unboxed variables on the catch
// entry in optimized code.
@ -10,9 +10,7 @@ import 'dart:typed_data';
import 'package:expect/expect.dart';
const NeverInline = "NeverInline";
@NeverInline
@pragma('vm:never-inline')
void testThrow(bool shouldThrow) {
var dbl = 0.0;
var i32 = 0;

View file

@ -2,7 +2,7 @@
// 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=5 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
import '../static_this.dart';

View file

@ -2,7 +2,7 @@
// 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=5 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
import "../super.dart";

View file

@ -8,13 +8,15 @@ import "package:expect/expect.dart";
// 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";
const pragma NeverInline = const bool.fromEnvironment("enable_inlining")
? null
: pragma('vm:never-inline');
// In AOT we need to force some functions to be inlined since we only build the
// unchecked entry-point when inlining.
const String AlwaysInline =
const bool.fromEnvironment("enable_inlining") ? "AlwaysInline" : "";
const pragma AlwaysInline = const bool.fromEnvironment("enable_inlining")
? pragma('vm:prefer-inline')
: null;
// 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

View file

@ -2,8 +2,8 @@
// 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
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
// Test that 'PolymorphicInstanceCall's against "this" go through the unchecked
// entrypoint. The use of optional arguments here encourages prologue sharing

View file

@ -2,8 +2,8 @@
// 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
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
// Test that 'PolymorphicInstanceCall's against "this" go through the unchecked
// entrypoint.

View file

@ -2,8 +2,8 @@
// 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=5
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=5 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
import '../static_this.dart';

View file

@ -2,8 +2,8 @@
// 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=5 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=5
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=5
import "../super.dart";

View file

@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
//
// No type checks are removed here, but we can skip the argument count check.
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
import "package:expect/expect.dart";
import "common.dart";

View file

@ -2,8 +2,8 @@
// 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
// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
// Test that typed calls against tearoffs go into the unchecked entrypoint.

View file

@ -6,13 +6,10 @@
// and decisions which parts of the instruction to emit use the same
// range information for instruction inputs.
// VMOptions=--enable-inlining-annotations --optimization_counter_threshold=10 --no-use-osr --no-background-compilation
// VMOptions=--optimization_counter_threshold=10 --no-use-osr --no-background-compilation
import "package:expect/expect.dart";
const alwaysInline = "AlwaysInline";
const neverInline = "NeverInline";
class Flag {
var value;
Flag(this.value);
@ -20,14 +17,14 @@ class Flag {
static final FLAG = new Flag(0);
}
@alwaysInline
@pragma('vm:prefer-inline')
void checkRange(bit) {
if (bit < 0 || bit > 31) {
throw "bit must be in [0, 31]";
}
}
@alwaysInline
@pragma('vm:prefer-inline')
bool isSet(flags, bit) {
checkRange(bit);
// Note: > 0 here instead of == 0 to prevent merging into
@ -35,7 +32,7 @@ bool isSet(flags, bit) {
return (flags & (1 << bit)) > 0;
}
@neverInline
@pragma('vm:never-inline')
bool bug(flags) {
var bit = Flag.FLAG.value;
checkRange(bit);

View file

@ -5,22 +5,19 @@
// Regression test for dartbug.com/30853: check that we assign correct range
// to Uint32 operations when creating them from Int64 operations.
// VMOptions=--optimization_counter_threshold=50 --no-background-compilation --enable-inlining-annotations
// VMOptions=--optimization_counter_threshold=50 --no-background-compilation
import "package:expect/expect.dart";
const NeverInline = "NeverInline";
const AlwaysInline = "AlwaysInline";
@NeverInline
@pragma('vm:never-inline')
noop(x) => x;
const int BITS32 = 0xFFFFFFFF;
@AlwaysInline
@pragma('vm:prefer-inline')
int toUint32(int x) => noop(x & BITS32);
@NeverInline
@pragma('vm:never-inline')
bitNotAsUint32(x) {
// After inlining we will have here BoxUint32(UnboxUint32(UnarySmiOp(~, x)))
// UnboxUint32 must have correct range assigned, otherwise we will not

View file

@ -2,25 +2,22 @@
// 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-inlining-annotations --optimization_counter_threshold=10 --no-use-osr --no-background-compilation
// VMOptions=--optimization_counter_threshold=10 --no-use-osr --no-background-compilation
// Test for truncating (wrap-around) integer arithmetic.
import "package:expect/expect.dart";
const alwaysInline = "AlwaysInline";
const neverInline = "NeverInline";
@neverInline
@pragma('vm:never-inline')
add_smi(var a, var b) => a + b;
@neverInline
@pragma('vm:never-inline')
add_mint(var a, var b) => a + b;
@neverInline
@pragma('vm:never-inline')
add_mint_consts() => 0x5000000000000000 + 0x6000000000000000;
@neverInline
@pragma('vm:never-inline')
test_add(var v2, var v3, var v3fxx, var v5fxx, var v7fxx, var n60xx) {
for (var i = 0; i < 20; i++) {
Expect.equals(5, add_smi(v2, v3));
@ -46,16 +43,16 @@ test_add(var v2, var v3, var v3fxx, var v5fxx, var v7fxx, var n60xx) {
}
}
@neverInline
@pragma('vm:never-inline')
sub_smi(var a, var b) => a - b;
@neverInline
@pragma('vm:never-inline')
sub_mint(var a, var b) => a - b;
@neverInline
@pragma('vm:never-inline')
sub_mint_consts() => (-0x5000000000000000) - 0x6000000000000000;
@neverInline
@pragma('vm:never-inline')
test_sub(var v2, var v3, var v3fxx, var v5fxx, var v7fxx, var n60xx) {
for (var i = 0; i < 20; i++) {
Expect.equals(1, sub_smi(v3, v2));
@ -81,16 +78,16 @@ test_sub(var v2, var v3, var v3fxx, var v5fxx, var v7fxx, var n60xx) {
}
}
@neverInline
@pragma('vm:never-inline')
mul_smi(var a, var b) => a * b;
@neverInline
@pragma('vm:never-inline')
mul_mint(var a, var b) => a * b;
@neverInline
@pragma('vm:never-inline')
mul_mint_consts() => 0x5000000000000001 * 0x6000000000000001;
@neverInline
@pragma('vm:never-inline')
test_mul(var v2, var v3, var v3fxx, var v5fxx, var v7fxx, var n60xx) {
for (var i = 0; i < 20; i++) {
Expect.equals(6, mul_smi(v2, v3));
@ -112,25 +109,25 @@ test_mul(var v2, var v3, var v3fxx, var v5fxx, var v7fxx, var n60xx) {
}
}
@neverInline
@pragma('vm:never-inline')
shl_smi(var a, var b) => a << b;
@neverInline
@pragma('vm:never-inline')
shl_mint(var a, var b) => a << b;
@neverInline
@pragma('vm:never-inline')
shl_mint_by_const16(var a) => a << 16;
@neverInline
@pragma('vm:never-inline')
shl_smi_by_const96(var a) => a << 96;
@neverInline
@pragma('vm:never-inline')
shl_mint_by_const96(var a) => a << 96;
@neverInline
@pragma('vm:never-inline')
shl_mint_consts() => 0x77665544aabbccdd << 48;
@neverInline
@pragma('vm:never-inline')
test_shl(var v2, var v3, var v8, var v40) {
for (var i = 0; i < 20; i++) {
Expect.equals(16, shl_smi(v2, v3));

View file

@ -2,15 +2,11 @@
// 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=--no-background-compilation --enable-inlining-annotations
// Test for overflow (wrap-around) during computations in range analysis.
import "package:expect/expect.dart";
const NeverInline = 'NeverInline';
@NeverInline
@pragma('vm:never-inline')
int foofoo(int b) {
for (int i = 0x7ffffffffffffffc; i <= b; i += 2) {
if (i < 0) {

View file

@ -78,10 +78,6 @@ DEFINE_FLAG(int,
500,
"Max. number of inlined calls per depth");
DEFINE_FLAG(bool, print_inlining_tree, false, "Print inlining tree");
DEFINE_FLAG(bool,
enable_inlining_annotations,
false,
"Enable inlining annotations");
DECLARE_FLAG(int, max_deoptimization_counter_threshold);
DECLARE_FLAG(bool, print_flow_graph);
@ -600,27 +596,6 @@ class PolymorphicInliner : public ValueObject {
const intptr_t caller_inlining_id_;
};
static bool HasAnnotation(const Function& function, const char* annotation) {
const Class& owner = Class::Handle(function.Owner());
const Library& library = Library::Handle(owner.library());
auto& metadata_or_error = Object::Handle(library.GetMetadata(function));
if (metadata_or_error.IsError()) {
Report::LongJump(Error::Cast(metadata_or_error));
}
const Array& metadata = Array::Cast(metadata_or_error);
if (metadata.Length() > 0) {
Object& val = Object::Handle();
for (intptr_t i = 0; i < metadata.Length(); i++) {
val = metadata.At(i);
if (val.IsString() && String::Cast(val).Equals(annotation)) {
return true;
}
}
}
return false;
}
static void ReplaceParameterStubs(Zone* zone,
FlowGraph* caller_graph,
InlinedCallData* call_data,
@ -926,10 +901,8 @@ class CallSiteInliner : public ValueObject {
return false;
}
const char* kNeverInlineAnnotation = "NeverInline";
if (FLAG_enable_inlining_annotations &&
HasAnnotation(function, kNeverInlineAnnotation)) {
TRACE_INLINING(THR_Print(" Bailout: NeverInline annotation\n"));
if (FlowGraphInliner::FunctionHasNeverInlinePragma(function)) {
TRACE_INLINING(THR_Print(" Bailout: vm:never-inline pragma\n"));
return false;
}
@ -2287,12 +2260,22 @@ static bool IsInlineableOperator(const Function& function) {
(function.name() == Symbols::Minus().raw());
}
bool FlowGraphInliner::FunctionHasPreferInlinePragma(const Function& function) {
Object& options = Object::Handle();
return Library::FindPragma(dart::Thread::Current(), /*only_core=*/false,
function, Symbols::vm_prefer_inline(), &options);
}
bool FlowGraphInliner::FunctionHasNeverInlinePragma(const Function& function) {
Object& options = Object::Handle();
return Library::FindPragma(dart::Thread::Current(), /*only_core=*/false,
function, Symbols::vm_never_inline(), &options);
}
bool FlowGraphInliner::AlwaysInline(const Function& function) {
const char* kAlwaysInlineAnnotation = "AlwaysInline";
if (FLAG_enable_inlining_annotations &&
HasAnnotation(function, kAlwaysInlineAnnotation)) {
if (FunctionHasPreferInlinePragma(function)) {
TRACE_INLINING(
THR_Print("AlwaysInline annotation for %s\n", function.ToCString()));
THR_Print("vm:prefer-inline pragma for %s\n", function.ToCString()));
return true;
}

View file

@ -115,6 +115,9 @@ class FlowGraphInliner : ValueObject {
bool AlwaysInline(const Function& function);
static bool FunctionHasPreferInlinePragma(const Function& function);
static bool FunctionHasNeverInlinePragma(const Function& function);
FlowGraph* flow_graph() const { return flow_graph_; }
intptr_t NextInlineId(const Function& function,
TokenPosition tp,

View file

@ -20,7 +20,6 @@ namespace dart {
DECLARE_FLAG(bool, profile_vm);
DECLARE_FLAG(bool, profile_vm_allocation);
DECLARE_FLAG(int, max_profile_depth);
DECLARE_FLAG(bool, enable_inlining_annotations);
DECLARE_FLAG(int, optimization_counter_threshold);
// Some tests are written assuming native stack trace profiling is disabled.
@ -2094,15 +2093,13 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BasicSourcePosition) {
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
"class A {\n"
" var a;\n"
" var b;\n"
" @NeverInline A() { }\n"
" @pragma('vm:never-inline') A() { }\n"
"}\n"
"class B {\n"
" @AlwaysInline\n"
" @pragma('vm:prefer-inline')\n"
" static boo() {\n"
" return new A();\n"
" }\n"
@ -2165,21 +2162,17 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BasicSourcePositionOptimized) {
EnableProfiler();
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
// We use the AlwaysInline and NeverInline annotations in this test.
SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
// Optimize quickly.
SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
"class A {\n"
" var a;\n"
" var b;\n"
" @NeverInline A() { }\n"
" @pragma('vm:never-inline') A() { }\n"
"}\n"
"class B {\n"
" @AlwaysInline\n"
" @pragma('vm:prefer-inline')\n"
" static boo() {\n"
" return new A();\n"
" }\n"
@ -2256,28 +2249,26 @@ ISOLATE_UNIT_TEST_CASE(Profiler_SourcePosition) {
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
"class A {\n"
" var a;\n"
" var b;\n"
" @NeverInline A() { }\n"
" @pragma('vm:never-inline') A() { }\n"
"}\n"
"class B {\n"
" @NeverInline\n"
" @pragma('vm:never-inline')\n"
" static oats() {\n"
" return boo();\n"
" }\n"
" @AlwaysInline\n"
" @pragma('vm:prefer-inline')\n"
" static boo() {\n"
" return new A();\n"
" }\n"
"}\n"
"class C {\n"
" @NeverInline bacon() {\n"
" @pragma('vm:never-inline') bacon() {\n"
" return fox();\n"
" }\n"
" @AlwaysInline fox() {\n"
" @pragma('vm:prefer-inline') fox() {\n"
" return B.oats();\n"
" }\n"
"}\n"
@ -2357,35 +2348,31 @@ ISOLATE_UNIT_TEST_CASE(Profiler_SourcePositionOptimized) {
EnableProfiler();
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
// We use the AlwaysInline and NeverInline annotations in this test.
SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
// Optimize quickly.
SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
"class A {\n"
" var a;\n"
" var b;\n"
" @NeverInline A() { }\n"
" @pragma('vm:never-inline') A() { }\n"
"}\n"
"class B {\n"
" @NeverInline\n"
" @pragma('vm:never-inline')\n"
" static oats() {\n"
" return boo();\n"
" }\n"
" @AlwaysInline\n"
" @pragma('vm:prefer-inline')\n"
" static boo() {\n"
" return new A();\n"
" }\n"
"}\n"
"class C {\n"
" @NeverInline bacon() {\n"
" @pragma('vm:never-inline') bacon() {\n"
" return fox();\n"
" }\n"
" @AlwaysInline fox() {\n"
" @pragma('vm:prefer-inline') fox() {\n"
" return B.oats();\n"
" }\n"
"}\n"
@ -2479,31 +2466,29 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BinaryOperatorSourcePosition) {
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
"class A {\n"
" var a;\n"
" var b;\n"
" @NeverInline A() { }\n"
" @pragma('vm:never-inline') A() { }\n"
"}\n"
"class B {\n"
" @NeverInline\n"
" @pragma('vm:never-inline')\n"
" static oats() {\n"
" return boo();\n"
" }\n"
" @AlwaysInline\n"
" @pragma('vm:prefer-inline')\n"
" static boo() {\n"
" return new A();\n"
" }\n"
"}\n"
"class C {\n"
" @NeverInline bacon() {\n"
" @pragma('vm:never-inline') bacon() {\n"
" return this + this;\n"
" }\n"
" @AlwaysInline operator+(C other) {\n"
" @pragma('vm:prefer-inline') operator+(C other) {\n"
" return fox();\n"
" }\n"
" @AlwaysInline fox() {\n"
" @pragma('vm:prefer-inline') fox() {\n"
" return B.oats();\n"
" }\n"
"}\n"
@ -2589,38 +2574,34 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BinaryOperatorSourcePositionOptimized) {
EnableProfiler();
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
// We use the AlwaysInline and NeverInline annotations in this test.
SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
// Optimize quickly.
SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
"class A {\n"
" var a;\n"
" var b;\n"
" @NeverInline A() { }\n"
" @pragma('vm:never-inline') A() { }\n"
"}\n"
"class B {\n"
" @NeverInline\n"
" @pragma('vm:never-inline')\n"
" static oats() {\n"
" return boo();\n"
" }\n"
" @AlwaysInline\n"
" @pragma('vm:prefer-inline')\n"
" static boo() {\n"
" return new A();\n"
" }\n"
"}\n"
"class C {\n"
" @NeverInline bacon() {\n"
" @pragma('vm:never-inline') bacon() {\n"
" return this + this;\n"
" }\n"
" @AlwaysInline operator+(C other) {\n"
" @pragma('vm:prefer-inline') operator+(C other) {\n"
" return fox();\n"
" }\n"
" @AlwaysInline fox() {\n"
" @pragma('vm:prefer-inline') fox() {\n"
" return B.oats();\n"
" }\n"
"}\n"

View file

@ -54,7 +54,6 @@ DEFINE_FLAG(bool,
DECLARE_FLAG(bool, enable_interpreter);
DECLARE_FLAG(int, max_deoptimization_counter_threshold);
DECLARE_FLAG(bool, enable_inlining_annotations);
DECLARE_FLAG(bool, trace_compiler);
DECLARE_FLAG(bool, trace_optimizing_compiler);
DECLARE_FLAG(int, max_polymorphic_checks);
@ -2343,9 +2342,6 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
if (Compiler::CanOptimizeFunction(thread, function)) {
if (FLAG_background_compilation) {
if (FLAG_enable_inlining_annotations) {
FATAL("Cannot enable inlining annotations and background compilation");
}
Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField());
while (!field.IsNull()) {
if (FLAG_trace_optimization || FLAG_trace_field_guards) {

View file

@ -450,8 +450,10 @@ class ObjectPointerVisitor;
V(string_param, ":string_param") \
V(string_param_length, ":string_param_length") \
V(toString, "toString") \
V(vm_prefer_inline, "vm:prefer-inline") \
V(vm_entry_point, "vm:entry-point") \
V(vm_exact_result_type, "vm:exact-result-type") \
V(vm_never_inline, "vm:never-inline") \
V(vm_non_nullable_result_type, "vm:non-nullable-result-type") \
V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn")

View file

@ -6,7 +6,7 @@
// from and stores to C memory are not aliased.
//
// SharedObjects=ffi_test_functions
// VMOptions=--deterministic --optimization-counter-threshold=50 --enable-inlining-annotations
// VMOptions=--deterministic --optimization-counter-threshold=50
library FfiTest;
@ -200,10 +200,7 @@ void testAliasFromAddressViaNativeFunction2() {
source.free();
}
// TODO(dacoharkes): Replace with @pragma annotations once available.
const NeverInline = 'NeverInline';
@NeverInline
@pragma('vm:never-inline')
Pointer<Int8> makeDerived(Pointer<Int64> source) =>
source.offsetBy(7).cast<Int8>();

View file

@ -4,7 +4,7 @@
//
// Dart test program for testing dart:ffi struct pointers.
//
// VMOptions=--deterministic --optimization-counter-threshold=50 --enable-inlining-annotations
// VMOptions=--deterministic --optimization-counter-threshold=50
library FfiTest;

View file

@ -2,12 +2,10 @@
// 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.
// Dart test for testing bitwise operations.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation --enable-inlining-annotations
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
import "package:expect/expect.dart";
const neverInline = "NeverInline";
void main() {
for (int i = 0; i < 4; i++) {
test();
@ -226,7 +224,7 @@ void testPrecedence(int a, int b, int c, int d) {
Expect.notEquals((a & b) << (c ^ d), a & b << c ^ d);
}
@neverInline
@pragma('vm:never-inline')
rightShift65Noinline(a) => a >> 65;
testRightShift65() {

View file

@ -2,17 +2,15 @@
// 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=--deterministic --enable-inlining-annotations --optimization_counter_threshold=10
// VMOptions=--deterministic--optimization_counter_threshold=10
import 'dart:typed_data';
import "package:expect/expect.dart";
const String NeverInline = 'NeverInline';
// Tests a few situations in which invariant instructions
// can be subject to CSE and LICM.
@NeverInline
@pragma('vm:never-inline')
int cse1(Int32List a, int n) {
int x = a[0];
for (int i = 0; i < n; i++) {
@ -23,7 +21,7 @@ int cse1(Int32List a, int n) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int cse2(Int32List a, int n) {
int x = a[0];
for (int i = 0; i < n; i++) {
@ -35,7 +33,7 @@ int cse2(Int32List a, int n) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm1(Int32List a, int n) {
int x = 0;
for (int i = 0; i < n; i++) {
@ -46,7 +44,7 @@ int licm1(Int32List a, int n) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm2(Int32List a) {
int x = 0;
for (int i = 0; i < 16; i++) {
@ -57,7 +55,7 @@ int licm2(Int32List a) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm3(Int32List a, bool cond) {
int x = 0;
for (int i = 0; i < 16; i++) {
@ -69,7 +67,7 @@ int licm3(Int32List a, bool cond) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm3_brk(Int32List a, bool cond) {
int x = 0;
for (int i = 0; i < 16; i++) {
@ -84,7 +82,7 @@ int licm3_brk(Int32List a, bool cond) {
int global;
@NeverInline
@pragma('vm:never-inline')
int licm4(Int32List a) {
int x = 0;
for (int i = 0; i < 16; i++) {
@ -97,7 +95,7 @@ int licm4(Int32List a) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm5(Int32List a) {
int x = 0;
// Anything in the loop header can be LICMed.
@ -107,7 +105,7 @@ int licm5(Int32List a) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm6(Int32List a, int n) {
int x = 0;
int i = 0;
@ -119,7 +117,7 @@ int licm6(Int32List a, int n) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm7(Int32List a, int n) {
int x = 0;
int i = 0;
@ -132,7 +130,7 @@ int licm7(Int32List a, int n) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm8(Int32List a, int n) {
int x = 0;
int i = 0;
@ -144,7 +142,7 @@ int licm8(Int32List a, int n) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm9(Int32List a) {
int x = 0;
int i = 0;
@ -157,7 +155,7 @@ int licm9(Int32List a) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm10(Int32List a, bool cond) {
int x = 0;
int i = 0;
@ -172,7 +170,7 @@ int licm10(Int32List a, bool cond) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm10_brk(Int32List a, bool cond) {
int x = 0;
int i = 0;
@ -187,7 +185,7 @@ int licm10_brk(Int32List a, bool cond) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int licm11(Int32List a) {
int x = 0;
while (true) {
@ -198,12 +196,12 @@ int licm11(Int32List a) {
return x;
}
@NeverInline
@pragma('vm:never-inline')
int foo() {
return global--;
}
@NeverInline
@pragma('vm:never-inline')
int licm12(Int32List a) {
int x = 0;
int i = 0;

View file

@ -2,41 +2,39 @@
// 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=--no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
// VMOptions=--no-background-compilation --optimization-counter-threshold=10
import "package:expect/expect.dart";
const NeverInline = "NeverInline";
class A<T> {
T field;
@NeverInline
@pragma('vm:never-inline')
set property(T v) {}
@NeverInline
@pragma('vm:never-inline')
void method(T x) {}
@NeverInline
@pragma('vm:never-inline')
void testMethod(bool violateType) {
A<dynamic> x = this;
x.method(violateType ? 10 : "10");
}
@NeverInline
@pragma('vm:never-inline')
void testSetter(bool violateType) {
A<dynamic> x = this;
x.property = violateType ? 10 : "10";
}
@NeverInline
@pragma('vm:never-inline')
void testField(bool violateType) {
A<dynamic> x = this;
x.field = violateType ? 10 : "10";
}
}
@NeverInline
@pragma('vm:never-inline')
void loop(A<String> obj, bool violateType) {
for (var i = 0; i < 100; i++) {
obj.testMethod(violateType);

View file

@ -2,41 +2,39 @@
// 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=--no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
// VMOptions=--no-background-compilation --optimization-counter-threshold=10
import "package:expect/expect.dart";
const NeverInline = "NeverInline";
class A<T> {
T field;
@NeverInline
@pragma('vm:never-inline')
set property(T v) {}
@NeverInline
@pragma('vm:never-inline')
void method(T x) {}
@NeverInline
@pragma('vm:never-inline')
void testMethod({bool violateType: false}) {
dynamic x = this;
x.method(violateType ? 10 : "10");
}
@NeverInline
@pragma('vm:never-inline')
void testSetter({bool violateType: false}) {
dynamic x = this;
x.property = violateType ? 10 : "10";
}
@NeverInline
@pragma('vm:never-inline')
void testField({bool violateType: false}) {
dynamic x = this;
x.field = violateType ? 10 : "10";
}
}
@NeverInline
@pragma('vm:never-inline')
void loop(A<String> obj, {bool violateType: false}) {
for (var i = 0; i < 100; i++) {
obj.testMethod(violateType: violateType);

View file

@ -3,25 +3,23 @@
// BSD-style license that can be found in the LICENSE file.
// Dart test program for testing try/catch statement without any exceptions
// being thrown.
// VMOptions=--optimization-counter-threshold=100 --no-background-compilation --enable-inlining-annotations
// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
// Test optional parameters updated inside try-catch
import "package:expect/expect.dart";
const noInline = "NeverInline";
@noInline
@pragma('vm:never-inline')
m1(int b) {
if (b == 1) throw 123;
}
@noInline
@pragma('vm:never-inline')
m2(int b) {
if (b == 2) throw 456;
}
@noInline
@pragma('vm:never-inline')
test1(int b, [int state = 0]) {
try {
state++;
@ -39,7 +37,7 @@ test1(int b, [int state = 0]) {
return "no throw";
}
@noInline
@pragma('vm:never-inline')
test2(int b, [int state]) {
state = 0;
try {

View file

@ -3,25 +3,23 @@
// BSD-style license that can be found in the LICENSE file.
// Dart test program for testing try/catch statement without any exceptions
// being thrown.
// VMOptions=--optimization-counter-threshold=100 --no-background-compilation --enable-inlining-annotations
// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
// Test local variables updated inside try-catch.
import "package:expect/expect.dart";
const noInline = "NeverInline";
@noInline
@pragma('vm:never-inline')
m1(int b) {
if (b == 1) throw 123;
}
@noInline
@pragma('vm:never-inline')
m2(int b) {
if (b == 2) throw 456;
}
@noInline
@pragma('vm:never-inline')
test(b) {
var state = 0;
try {

View file

@ -1,15 +1,13 @@
// Copyright (c) 2017, 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=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation --enable_inlining_annotations
const NeverInline = "NeverInline";
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
foo(n) {
return new List(n);
}
@NeverInline
@pragma('vm:never-inline')
bar(n) {
try {
return foo(n);

View file

@ -1,11 +1,9 @@
// Copyright (c) 2017, 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=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation --enable_inlining_annotations
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
const NeverInline = "NeverInline";
@NeverInline
@pragma('vm:never-inline')
foo(n) {
try {
return new List(n);

View file

@ -2,15 +2,13 @@
// 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=--deterministic --optimization_counter_threshold=10 --enable-inlining-annotations
// VMOptions=--deterministic --optimization_counter_threshold=10
// Test on specialized vs non-specialized inlining.
import 'dart:core';
import "package:expect/expect.dart";
const String NeverInline = 'NeverInline';
// To inline or not to inline, that is the question?
int foo(int k) {
switch (k) {
@ -275,14 +273,14 @@ int foo(int k) {
}
}
@NeverInline
@pragma('vm:never-inline')
int bar() {
// Here we should inline! The inlined size is very small
// after specialization for the constant arguments.
return foo(1) + foo(12);
}
@NeverInline
@pragma('vm:never-inline')
int baz(int i) {
// Here we should not inline! The inlined size is too large,
// just keep the original method. In fact, we can use the cached

View file

@ -2,17 +2,14 @@
// 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 various optimizations and deoptimizations of optimizing compiler..
// VMOptions=--enable-inlining-annotations --no-background-compilation --optimization-counter-threshold=1000
// VMOptions=--no-background-compilation --optimization-counter-threshold=1000
import "package:expect/expect.dart";
import "dart:typed_data";
const noInline = "NeverInline";
const alwaysInline = "AlwaysInline";
var list = new Uint32List(1);
@noInline
@pragma('vm:never-inline')
testuint32(bool b) {
var t;
if (b) {

View file

@ -2,13 +2,11 @@
// 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 various optimizations and deoptimizations of optimizing compiler..
// VMOptions=--enable-inlining-annotations --no-background-compilation --optimization-counter-threshold=1000
// VMOptions=--no-background-compilation --optimization-counter-threshold=1000
import "package:expect/expect.dart";
const noInline = "NeverInline";
@noInline
@pragma('vm:never-inline')
testuint32(y) {
int x = y;
if (x != null) {

View file

@ -2,7 +2,7 @@
// 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 deoptimization on an optimistically hoisted smi check.
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation --enable-inlining-annotations
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
// Test that lazy deoptimization works if the program returns to a function
// that is scheduled for lazy deoptimization via an exception.
@ -13,9 +13,7 @@ class C {
dynamic x = 42;
}
const NeverInline = "NeverInline";
@NeverInline
@pragma('vm:never-inline')
AA(C c, bool b) {
if (b) {
c.x = 2.5;
@ -23,7 +21,7 @@ AA(C c, bool b) {
}
}
@NeverInline
@pragma('vm:never-inline')
T1(C c, bool b) {
try {
AA(c, b);
@ -35,7 +33,7 @@ T1(C c, bool b) {
return c.x + 1;
}
@NeverInline
@pragma('vm:never-inline')
T2(C c, bool b) {
try {
AA(c, b);

View file

@ -2,7 +2,7 @@
// 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 deoptimization on an optimistically hoisted smi check.
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation --enable-inlining-annotations
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
// Test that lazy deoptimization works if the program returns to a function
// that is scheduled for lazy deoptimization via an exception.
@ -13,9 +13,7 @@ class C {
dynamic x = 42;
}
const NeverInline = "NeverInline";
@NeverInline
@pragma('vm:never-inline')
AA(C c, bool b) {
if (b) {
c.x = 2.5;
@ -23,7 +21,7 @@ AA(C c, bool b) {
}
}
@NeverInline
@pragma('vm:never-inline')
T1(C c, bool b) {
try {
AA(c, b);
@ -31,7 +29,7 @@ T1(C c, bool b) {
return c.x + 1;
}
@NeverInline
@pragma('vm:never-inline')
T2(C c, bool b) {
try {
AA(c, b);

View file

@ -3,22 +3,19 @@
// BSD-style license that can be found in the LICENSE file.
// Test correctness of side effects tracking used by load to load forwarding.
// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
// VMOptions=--no-use-osr --optimization-counter-threshold=10 --no-background-compilation
import "package:expect/expect.dart";
const alwaysInline = "AlwaysInline";
const noInline = "NeverInline";
B G;
@noInline
@pragma('vm:never-inline')
modify() {
G.bval = 123;
}
class B {
@alwaysInline
@pragma('vm:prefer-inline')
poly() {
G = this;
modify();
@ -32,10 +29,10 @@ class C {
poly() => null;
}
@alwaysInline
@pragma('vm:prefer-inline')
foo(obj) => obj.poly();
@noInline
@pragma('vm:never-inline')
test() {
var b = new B();

View file

@ -3,21 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
// Test correctness of side effects tracking used by load to load forwarding.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations --no-background-compilation
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
// Tests correct handling of redefinitions in aliasing computation.
import "package:expect/expect.dart";
const alwaysInline = "AlwaysInline";
const noInline = "NeverInline";
var H = true;
class A {
B bb;
@alwaysInline
@pragma('vm:prefer-inline')
poly(p) {
if (H) {
bb = p;
@ -31,16 +28,16 @@ class A {
class B {
int bval = -1;
@alwaysInline
@pragma('vm:prefer-inline')
poly(p) {
return bval;
}
}
@alwaysInline
@pragma('vm:prefer-inline')
foo(obj, p) => obj.poly(p);
@noInline
@pragma('vm:never-inline')
test() {
A a = new A();
B b = new B();

View file

@ -3,27 +3,24 @@
// BSD-style license that can be found in the LICENSE file.
// Test correctness of side effects tracking used by load to load forwarding.
// VMOptions=--no-use-osr --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
// VMOptions=--no-use-osr --optimization-counter-threshold=10 --no-background-compilation
// Tests correct handling of redefinitions in aliasing computation.
import "package:expect/expect.dart";
const alwaysInline = "AlwaysInline";
const noInline = "NeverInline";
B G;
class A {
int val = -1;
@alwaysInline
@pragma('vm:prefer-inline')
poly(p) {
p.aa = this;
}
}
@noInline
@pragma('vm:never-inline')
modify() {
G.aa.val = 123;
}
@ -31,7 +28,7 @@ modify() {
class B {
A aa;
@alwaysInline
@pragma('vm:prefer-inline')
poly(p) {
G = this;
foo2(p, this);
@ -39,13 +36,13 @@ class B {
}
}
@alwaysInline
@pragma('vm:prefer-inline')
foo(obj, p) => obj.poly(p);
@alwaysInline
@pragma('vm:prefer-inline')
foo2(obj, p) => obj.poly(p);
@noInline
@pragma('vm:never-inline')
testfunc() {
var a = new A();
var b = new B();

View file

@ -3,21 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
// Test correctness of side effects tracking used by load to load forwarding.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --enable-inlining-annotations --no-background-compilation
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
// Tests correct handling of redefinitions in aliasing computation.
import "package:expect/expect.dart";
const alwaysInline = "AlwaysInline";
const noInline = "NeverInline";
var H = true;
class A {
B bb;
@alwaysInline
@pragma('vm:prefer-inline')
poly(p) {
if (H) {
bb = p;
@ -31,16 +28,16 @@ class A {
class B {
int bval = -1;
@alwaysInline
@pragma('vm:prefer-inline')
poly(p) {
return bval;
}
}
@alwaysInline
@pragma('vm:prefer-inline')
foo(obj, p) => obj.poly(p);
@noInline
@pragma('vm:never-inline')
test() {
A a = new A();
B b = new B();

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015, 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=--stacktrace-every=3 --optimization-counter-threshold=10 --enable-inlining-annotations --no-background-compilation
// VMOptions=--stacktrace-every=3 --optimization-counter-threshold=10 --no-background-compilation
// Test generating stacktraces with inlining and deferred code.
// Regression test for issue dartbug.com/22331
@ -25,9 +25,7 @@ foo(o, value) {
return value;
}
const NeverInline = 'NeverInline';
@NeverInline
@pragma('vm:never-inline')
baz(x, y, z) => z;
bar(o) {

View file

@ -9,10 +9,8 @@
import 'dart:core';
import "package:expect/expect.dart";
const String NeverInline = 'NeverInline';
class Z {
@NeverInline
@pragma('vm:never-inline')
check(int a, int b, String c, List<int> d) {
Expect.equals(a, 42);
Expect.equals(b, global_bazz);
@ -25,29 +23,29 @@ Z z = new Z();
int global_bazz = 123;
int global_more_bazz = 456;
@NeverInline
@pragma('vm:never-inline')
int bazz() {
return ++global_bazz;
}
@NeverInline
@pragma('vm:never-inline')
int more_bazz() {
return ++global_more_bazz;
}
@NeverInline
@pragma('vm:never-inline')
int bar(int i) {
return i - 1;
}
@NeverInline
@pragma('vm:never-inline')
List<int> spread(int v, List<int> x) {
return [v, ...x];
}
// Long running control-flow collection (block expression),
// leaves the stack non-empty during a potential OSR.
@NeverInline
@pragma('vm:never-inline')
List<int> test1(int n) {
return spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
}
@ -76,7 +74,7 @@ List<int> test3(int n) {
// Long running control-flow collection (block expression),
// leaves the stack non-empty during a potential OSR.
@NeverInline
@pragma('vm:never-inline')
List<int> test4(int n) {
var x = [10] +
z.check(42, bazz(), 'abc',
@ -86,7 +84,7 @@ List<int> test4(int n) {
// Long running control-flow collection (block expression) inside outer
// loop, also leaves the stack non-empty during a potential OSR.
@NeverInline
@pragma('vm:never-inline')
List<int> test5(int m, int n) {
List<int> x = [];
for (int k = 0; k < m; k++) {

View file

@ -4,7 +4,7 @@
import 'regress_27671_test.dart';
@AlwaysInline
@pragma('vm:prefer-inline')
void check(f, x) {
assert(f(x) && true);
}

View file

@ -2,22 +2,19 @@
// 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_asserts --enable-inlining-annotations --optimization-counter-threshold=10 --no-background-compilation
// VMOptions=--enable_asserts --optimization-counter-threshold=10 --no-background-compilation
import 'package:expect/expect.dart';
import 'regress_27671_other.dart';
const AlwaysInline = "AlwaysInline";
const NeverInline = "NeverInline";
@AlwaysInline
@pragma('vm:prefer-inline')
bounce(x) {
for (int i = 0; i < 10; i++) {
check(f, x);
}
}
@AlwaysInline
@pragma('vm:prefer-inline')
bool f(y) => y > 0;
main() {

View file

@ -2,11 +2,9 @@
// 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=--optimization-filter=triggerBug --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=2
// VMOptions=--optimization-filter=triggerBug --no-background-compilation --optimization-counter-threshold=2
const String NeverInline = 'NeverInline';
@NeverInline
@pragma('vm:never-inline')
dynamic triggerGC() {
var a = [];
for (int i = 0; i < 100; ++i) {
@ -15,12 +13,12 @@ dynamic triggerGC() {
return a;
}
@NeverInline
@pragma('vm:never-inline')
void fillLowerStackWithReturnAddresses() {
recursive(20);
}
@NeverInline
@pragma('vm:never-inline')
dynamic recursive(dynamic n) {
if (n > 0) {
recursive(n - 1);
@ -29,7 +27,7 @@ dynamic recursive(dynamic n) {
}
class Box {
@NeverInline
@pragma('vm:never-inline')
Box get value => global;
}
@ -39,7 +37,7 @@ main() {
bool isTrue = true;
bool hasProblem = true;
@NeverInline
@pragma('vm:never-inline')
void triggerBug(Box box) {
triggerGC();

View file

@ -8,27 +8,25 @@
import "package:expect/expect.dart";
const String NeverInline = 'NeverInline';
List<int> mX = new List(1);
@NeverInline
@pragma('vm:never-inline')
int foo() {
return mX[8589934591];
}
@NeverInline
@pragma('vm:never-inline')
foo_store() {
mX[8589934591] = 0;
}
@NeverInline
@pragma('vm:never-inline')
int bar() {
List<int> x = new List(1);
return x[8589934591];
}
@NeverInline
@pragma('vm:never-inline')
bar_store() {
List<int> x = new List(1);
x[8589934591] = 0;

View file

@ -8,11 +8,9 @@
import "package:expect/expect.dart";
const String NeverInline = 'NeverInline';
double v = 0;
@NeverInline
@pragma('vm:never-inline')
int foo(int a, int p, int q) {
double p1 = 0;
double p2 = 0;

View file

@ -5,15 +5,13 @@
// Don't LICM AOT's generic bounds check reference beyond other exception.
// (dartbug.com/36803).
//
// VMOptions=--deterministic --optimization_level=3 --enable-inlining-annotations
// VMOptions=--deterministic --optimization_level=3
import "package:expect/expect.dart";
const String NeverInline = 'NeverInline';
String var1 = 'Hdi\u{1f600}T';
@NeverInline
@pragma('vm:never-inline')
int foo() {
List<int> a = [1, 2, 3, 4];
int x = 0;

View file

@ -2,13 +2,10 @@
// 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-inlining-annotations --optimization-counter-threshold=1000 --no-background-compilation
// VMOptions=--optimization-counter-threshold=1000 --no-background-compilation
// Regression test for correct LICM and type propagation.
const AlwaysInline = "AlwaysInline";
const NeverInline = "NeverInline";
class Attribute {
final id = 123;
}
@ -18,7 +15,7 @@ abstract class Name {
final String name;
get attr;
@AlwaysInline
@pragma('vm:prefer-inline')
int compareTo(other) {
int nameCompare = name.compareTo(other.name);
if (nameCompare != 0) return nameCompare;

View file

@ -2,12 +2,10 @@
// 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=--deterministic --optimization-counter-threshold=102 --enable-inlining-annotations --optimization-filter=Box_
// VMOptions=--deterministic --optimization-counter-threshold=102 --optimization-filter=Box_
import 'package:expect/expect.dart';
const String NeverInline = 'NeverInline';
const String AlwaysInline = 'AlwaysInline';
const int kLimit = 100;
main() {
@ -20,14 +18,14 @@ main() {
testMints(2048);
}
@NeverInline
@pragma('vm:never-inline')
optimizeConstructor(int value) {
for (int i = 0; i < kLimit; ++i) {
new Box(milliseconds: value);
}
}
@NeverInline
@pragma('vm:never-inline')
optimizeMicroseconds(int value) {
final d = new Box(milliseconds: value);
for (int i = 0; i < kLimit; ++i) {
@ -35,7 +33,7 @@ optimizeMicroseconds(int value) {
}
}
@NeverInline
@pragma('vm:never-inline')
optimizeMilliseconds(int value) {
final d = new Box(seconds: value);
for (int i = 0; i < kLimit; ++i) {
@ -43,7 +41,7 @@ optimizeMilliseconds(int value) {
}
}
@NeverInline
@pragma('vm:never-inline')
testMints(int value) {
final d = new Box(seconds: value);
for (int i = 0; i < kLimit; ++i) {
@ -57,7 +55,7 @@ int c = 0;
class Box {
final int _value;
@NeverInline
@pragma('vm:never-inline')
Box(
{int days: 0,
int hours: 0,
@ -74,9 +72,9 @@ class Box {
Box._microseconds(this._value);
@NeverInline
@pragma('vm:never-inline')
int get inMilliseconds => _value ~/ 1000;
@NeverInline
@pragma('vm:never-inline')
int get inMicroseconds => _value;
}

View file

@ -1,23 +1,21 @@
// Copyright (c) 2017, 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=--no-background-compilation --enable-inlining-annotations
// VMOptions=--no-background-compilation
const NeverInline = 'NeverInline';
@NeverInline
@pragma('vm:never-inline')
doSomething() {
print("Hello!");
}
@NeverInline
@pragma('vm:never-inline')
maybeThrow(bool doThrow) {
if (doThrow) {
throw new Exception();
}
}
@NeverInline
@pragma('vm:never-inline')
run(action) {
try { action(); } catch(e) {}
}

View file

@ -2,20 +2,17 @@
// 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-inlining-annotations --optimization-counter-threshold=10 --no-background-compilation
const AlwaysInline = "AlwaysInline";
const NeverInline = "NeverInline";
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
abstract class A<T extends A<T>> {
@AlwaysInline
@pragma('vm:prefer-inline')
f(x) => new R<T>(x);
}
class B extends A<B> {}
class R<T> {
@AlwaysInline
@pragma('vm:prefer-inline')
R(T field);
}
@ -26,7 +23,7 @@ class D extends C {}
// f will be inlined and T=B will be forwarded to AssertAssignable in the
// R. However B will be wrapped in the TypeRef which breaks runtime TypeCheck
// function (Instance::IsInstanceOf does not work for TypeRefs).
@NeverInline
@pragma('vm:never-inline')
f(o) => new B().f(o);
main() {