xref: /aosp_15_r20/art/test/570-checker-osr-locals/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
main(String[] args)18*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
19*795d594fSAndroid Build Coastguard Worker     System.loadLibrary(args[0]);
20*795d594fSAndroid Build Coastguard Worker     while (runTests(true));
21*795d594fSAndroid Build Coastguard Worker     runTests(false);
22*795d594fSAndroid Build Coastguard Worker     runSmaliTest();
23*795d594fSAndroid Build Coastguard Worker   }
24*795d594fSAndroid Build Coastguard Worker 
runTests(boolean warmup)25*795d594fSAndroid Build Coastguard Worker   public static boolean runTests(boolean warmup) {
26*795d594fSAndroid Build Coastguard Worker     if (warmup) {
27*795d594fSAndroid Build Coastguard Worker       return isInInterpreter("runTests");
28*795d594fSAndroid Build Coastguard Worker     }
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker     // Several local variables which live across calls below,
31*795d594fSAndroid Build Coastguard Worker     // thus they are likely to be saved in callee save registers.
32*795d594fSAndroid Build Coastguard Worker     int i = $noinline$magicValue();
33*795d594fSAndroid Build Coastguard Worker     long l = $noinline$magicValue();
34*795d594fSAndroid Build Coastguard Worker     float f = $noinline$magicValue();
35*795d594fSAndroid Build Coastguard Worker     double d = $noinline$magicValue();
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker     // The calls below will OSR.  We pass the expected value in
38*795d594fSAndroid Build Coastguard Worker     // argument, which should be saved in callee save register.
39*795d594fSAndroid Build Coastguard Worker     if ($noinline$returnInt(53) != 53) {
40*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected return value");
41*795d594fSAndroid Build Coastguard Worker     }
42*795d594fSAndroid Build Coastguard Worker     if ($noinline$returnFloat(42.2f) != 42.2f) {
43*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected return value");
44*795d594fSAndroid Build Coastguard Worker     }
45*795d594fSAndroid Build Coastguard Worker     if ($noinline$returnDouble(Double.longBitsToDouble(0xF000000000001111L)) !=
46*795d594fSAndroid Build Coastguard Worker         Double.longBitsToDouble(0xF000000000001111L)) {
47*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected return value ");
48*795d594fSAndroid Build Coastguard Worker     }
49*795d594fSAndroid Build Coastguard Worker     if ($noinline$returnLong(0xFFFF000000001111L) != 0xFFFF000000001111L) {
50*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected return value");
51*795d594fSAndroid Build Coastguard Worker     }
52*795d594fSAndroid Build Coastguard Worker 
53*795d594fSAndroid Build Coastguard Worker     // Check that the register used in callee did not clober our value.
54*795d594fSAndroid Build Coastguard Worker     if (i != $noinline$magicValue()) {
55*795d594fSAndroid Build Coastguard Worker       throw new Error("Corrupted int local variable in caller");
56*795d594fSAndroid Build Coastguard Worker     }
57*795d594fSAndroid Build Coastguard Worker     if (l != $noinline$magicValue()) {
58*795d594fSAndroid Build Coastguard Worker       throw new Error("Corrupted long local variable in caller");
59*795d594fSAndroid Build Coastguard Worker     }
60*795d594fSAndroid Build Coastguard Worker     if (f != $noinline$magicValue()) {
61*795d594fSAndroid Build Coastguard Worker       throw new Error("Corrupted float local variable in caller");
62*795d594fSAndroid Build Coastguard Worker     }
63*795d594fSAndroid Build Coastguard Worker     if (d != $noinline$magicValue()) {
64*795d594fSAndroid Build Coastguard Worker       throw new Error("Corrupted double local variable in caller");
65*795d594fSAndroid Build Coastguard Worker     }
66*795d594fSAndroid Build Coastguard Worker     return true;
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker 
runSmaliTest()69*795d594fSAndroid Build Coastguard Worker   public static void runSmaliTest() {
70*795d594fSAndroid Build Coastguard Worker     try {
71*795d594fSAndroid Build Coastguard Worker       Class<?> c = Class.forName("WeirdLoop");
72*795d594fSAndroid Build Coastguard Worker       // Make sure `WeirdLoop` is visibly initialized to avoid waiting for OSR
73*795d594fSAndroid Build Coastguard Worker       // for the `--jit-on=first-use` configuration.
74*795d594fSAndroid Build Coastguard Worker       makeVisiblyInitialized();
75*795d594fSAndroid Build Coastguard Worker       int result = (int) c.getDeclaredMethod("weirdLoop").invoke(null);
76*795d594fSAndroid Build Coastguard Worker       if (result != 42) {
77*795d594fSAndroid Build Coastguard Worker         throw new Error("Unexpected result: " + result);
78*795d594fSAndroid Build Coastguard Worker       }
79*795d594fSAndroid Build Coastguard Worker     } catch (Throwable t) {
80*795d594fSAndroid Build Coastguard Worker       t.printStackTrace();
81*795d594fSAndroid Build Coastguard Worker     }
82*795d594fSAndroid Build Coastguard Worker   }
83*795d594fSAndroid Build Coastguard Worker 
$noinline$magicValue()84*795d594fSAndroid Build Coastguard Worker   public static int $noinline$magicValue() {
85*795d594fSAndroid Build Coastguard Worker     return 42;
86*795d594fSAndroid Build Coastguard Worker   }
87*795d594fSAndroid Build Coastguard Worker 
$noinline$returnInt(int result)88*795d594fSAndroid Build Coastguard Worker   public static int $noinline$returnInt(int result) {
89*795d594fSAndroid Build Coastguard Worker     // If we are running in non-JIT mode, or were unlucky enough to get this method
90*795d594fSAndroid Build Coastguard Worker     // already JITted, skip the wait for OSR code.
91*795d594fSAndroid Build Coastguard Worker     if (isInInterpreter("$noinline$returnInt")) {
92*795d594fSAndroid Build Coastguard Worker       while (!isInOsrCode("$noinline$returnInt")) {}
93*795d594fSAndroid Build Coastguard Worker     }
94*795d594fSAndroid Build Coastguard Worker     return result;
95*795d594fSAndroid Build Coastguard Worker   }
96*795d594fSAndroid Build Coastguard Worker 
$noinline$returnFloat(float result)97*795d594fSAndroid Build Coastguard Worker   public static float $noinline$returnFloat(float result) {
98*795d594fSAndroid Build Coastguard Worker     // If we are running in non-JIT mode, or were unlucky enough to get this method
99*795d594fSAndroid Build Coastguard Worker     // already JITted, skip the wait for OSR code.
100*795d594fSAndroid Build Coastguard Worker     if (isInInterpreter("$noinline$returnFloat")) {
101*795d594fSAndroid Build Coastguard Worker       while (!isInOsrCode("$noinline$returnFloat")) {}
102*795d594fSAndroid Build Coastguard Worker     }
103*795d594fSAndroid Build Coastguard Worker     return result;
104*795d594fSAndroid Build Coastguard Worker   }
105*795d594fSAndroid Build Coastguard Worker 
$noinline$returnDouble(double result)106*795d594fSAndroid Build Coastguard Worker   public static double $noinline$returnDouble(double result) {
107*795d594fSAndroid Build Coastguard Worker     // If we are running in non-JIT mode, or were unlucky enough to get this method
108*795d594fSAndroid Build Coastguard Worker     // already JITted, skip the wait for OSR code.
109*795d594fSAndroid Build Coastguard Worker     if (isInInterpreter("$noinline$returnDouble")) {
110*795d594fSAndroid Build Coastguard Worker       while (!isInOsrCode("$noinline$returnDouble")) {}
111*795d594fSAndroid Build Coastguard Worker     }
112*795d594fSAndroid Build Coastguard Worker     return result;
113*795d594fSAndroid Build Coastguard Worker   }
114*795d594fSAndroid Build Coastguard Worker 
$noinline$returnLong(long result)115*795d594fSAndroid Build Coastguard Worker   public static long $noinline$returnLong(long result) {
116*795d594fSAndroid Build Coastguard Worker     // If we are running in non-JIT mode, or were unlucky enough to get this method
117*795d594fSAndroid Build Coastguard Worker     // already JITted, skip the wait for OSR code.
118*795d594fSAndroid Build Coastguard Worker     if (isInInterpreter("$noinline$returnLong")) {
119*795d594fSAndroid Build Coastguard Worker       while (!isInOsrCode("$noinline$returnLong")) {}
120*795d594fSAndroid Build Coastguard Worker     }
121*795d594fSAndroid Build Coastguard Worker     return result;
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
isInOsrCode(String methodName)124*795d594fSAndroid Build Coastguard Worker   public static native boolean isInOsrCode(String methodName);
isInInterpreter(String methodName)125*795d594fSAndroid Build Coastguard Worker   public static native boolean isInInterpreter(String methodName);
makeVisiblyInitialized()126*795d594fSAndroid Build Coastguard Worker   public static native void makeVisiblyInitialized();
127*795d594fSAndroid Build Coastguard Worker }
128