// 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. // 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 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 spread(int v, List 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 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 test2(int n) { List 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 test3(int n) { List 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 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 test5(int m, int n) { List 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 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); } }