blob: 9f1407675a92d2cb6e93c540ea3349f2e0aec02c [file] [log] [blame]
// Copyright (c) 2019, 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.
// @dart = 2.9
// Test with OSR on non-empty stack (block expression).
import 'dart:core';
import "package:expect/expect.dart";
class Z {
@pragma('vm:never-inline')
check(int a, int b, String c, List<int> d) {
Expect.equals(a, 42);
Expect.equals(b, global_bazz);
Expect.equals(c, 'abc');
return d;
}
}
Z z = new Z();
int global_bazz = 123;
int global_more_bazz = 456;
@pragma('vm:never-inline')
int bazz() {
return ++global_bazz;
}
@pragma('vm:never-inline')
int more_bazz() {
return ++global_more_bazz;
}
@pragma('vm:never-inline')
int bar(int i) {
return i - 1;
}
@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.
@pragma('vm:never-inline')
List<int> test1(int n) {
return spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
}
// Long running control-flow collection (block expression) inside outer
// loop, leaves the stack non-empty during a potential OSR.
List<int> test2(int n) {
List<int> x = [];
for (int k = 0; k < 10; k++) {
x += spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
}
return x;
}
// Long running control-flow collection (block expression) inside two
// outer loops, leaves the stack non-empty during a potential OSR.
List<int> test3(int n) {
List<int> x = [];
for (int k = 0; k < 4; k++) {
for (int j = 0; j < 4; j++) {
x += spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
}
}
return x;
}
// Long running control-flow collection (block expression),
// leaves the stack non-empty during a potential OSR.
@pragma('vm:never-inline')
List<int> test4(int n) {
var x = [10] +
z.check(42, bazz(), 'abc',
[more_bazz(), for (int i = 0; i < n; i++) bar(2 * i)]);
return x;
}
// Long running control-flow collection (block expression) inside outer
// loop, also leaves the stack non-empty during a potential OSR.
@pragma('vm:never-inline')
List<int> test5(int m, int n) {
List<int> x = [];
for (int k = 0; k < m; k++) {
x += [10] +
z.check(42, bazz(), 'abc',
[more_bazz(), for (int i = 0; i < n; i++) bar(2 * i)]);
}
return x;
}
List<int> globalList = [
1,
for (int loc1 = 2; loc1 <= 100000; loc1++) loc1,
100001
];
main() {
int n = 20000;
int g = 457;
var a = test1(n);
Expect.equals(a.length, n + 1);
for (int k = 0; k < n + 1; k++) {
int expect = (k == 0) ? g++ : k - 1;
Expect.equals(a[k], expect);
}
var b = test2(n);
Expect.equals(b.length, 10 * (n + 1));
for (int i = 0, k = 0; i < 10 * (n + 1); i++) {
int expect = (k == 0) ? g++ : k - 1;
Expect.equals(b[i], expect);
if (++k == (n + 1)) k = 0;
}
var c = test3(n);
Expect.equals(c.length, 16 * (n + 1));
for (int i = 0, k = 0; i < 16 * (n + 1); i++) {
int expect = (k == 0) ? g++ : k - 1;
Expect.equals(c[i], expect);
if (++k == (n + 1)) k = 0;
}
var d = test4(n);
Expect.equals(d.length, n + 2);
for (int k = 0; k < n + 2; k++) {
int expect = k <= 1 ? ((k == 0) ? 10 : g++) : -5 + 2 * k;
Expect.equals(d[k], expect);
}
var e = test5(10, n);
Expect.equals(e.length, 10 * (n + 2));
for (int i = 0, k = 0; i < 10 * (n + 2); i++) {
int expect = k <= 1 ? ((k == 0) ? 10 : g++) : -5 + 2 * k;
Expect.equals(e[i], expect);
if (++k == (n + 2)) k = 0;
}
Expect.isTrue(globalList != null);
Expect.equals(100001, globalList.length);
for (int i = 0; i < globalList.length; i++) {
Expect.equals(globalList[i], i + 1);
}
}