blob: 4ad88582ca961957af9be08b914038109fbf83f0 [file] [log] [blame]
Artem Serove65ade72019-07-25 21:04:16 +01001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// This test checks that values (e.g. induction variable) are properly set for SuspendCheck
18// environment in the SIMD loop; by causing asynchronous deoptimization in debuggable mode we
19// we observe the values.
20public class SimdLoop implements Runnable {
21 static final int numberOfThreads = 2;
22 volatile static boolean sExitFlag = false;
23 volatile static boolean sEntered = false;
24 int threadIndex;
25
26 SimdLoop(int index) {
27 threadIndex = index;
28 }
29
30 public static void main() throws Exception {
31 final Thread[] threads = new Thread[numberOfThreads];
32 for (int t = 0; t < threads.length; t++) {
33 threads[t] = new Thread(new SimdLoop(t));
34 threads[t].start();
35 }
36 for (Thread t : threads) {
37 t.join();
38 }
39
40 System.out.println("Simd loop finishing");
41 }
42
Vladimir Marko54434932019-07-31 13:18:36 +010043 static final int kArraySize = 3000000;
Artem Serove65ade72019-07-25 21:04:16 +010044
45 public void expectEqual(int value, int expected) {
46 if (value != expected) {
47 throw new Error("Expected: " + expected + ", found: " + value);
48 }
49 }
50
51 public void $noinline$busyLoop() {
52 Main.assertIsManaged();
53
54 int[] array = new int[kArraySize];
55 sEntered = true;
56
57 // On Arm64:
Artem Serov5d93b882019-08-01 15:00:01 +010058 // These loops are likely to be vectorized; when deoptimizing to interpreter the induction
Artem Serove65ade72019-07-25 21:04:16 +010059 // variable i will be set to wrong value (== 0).
Artem Serov5d93b882019-08-01 15:00:01 +010060 //
61 // Copy-paste instead of nested loop is here to avoid extra loop suspend check.
62 for (int i = 0; i < kArraySize; i++) {
63 array[i]++;
64 }
65 for (int i = 0; i < kArraySize; i++) {
66 array[i]++;
67 }
68 for (int i = 0; i < kArraySize; i++) {
69 array[i]++;
70 }
Artem Serove65ade72019-07-25 21:04:16 +010071 for (int i = 0; i < kArraySize; i++) {
72 array[i]++;
73 }
74
75 // We might have managed to execute the whole loop before deoptimizeAll() happend.
76 if (sExitFlag) {
77 Main.assertIsInterpreted();
78 }
Artem Serove65ade72019-07-25 21:04:16 +010079 // Regression: the value of the induction variable might have been set to 0 when
80 // deoptimizing causing to have another array[0]++.
Artem Serov5d93b882019-08-01 15:00:01 +010081 expectEqual(array[0], 4);
Artem Serove65ade72019-07-25 21:04:16 +010082 }
83
84 public void run() {
85 if (threadIndex == 0) {
86 while (!sEntered) {
87 Thread.yield();
88 }
89
Artem Serove65ade72019-07-25 21:04:16 +010090 Main.deoptimizeAll();
91 sExitFlag = true;
92 } else {
93 $noinline$busyLoop();
94 }
95 }
96}