xref: /aosp_15_r20/art/test/552-checker-sharpening/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2015 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 public class Main {
18 
assertIntEquals(int expected, int result)19   public static void assertIntEquals(int expected, int result) {
20     if (expected != result) {
21       throw new Error("Expected: " + expected + ", found: " + result);
22     }
23   }
24 
assertStringEquals(String expected, String result)25   public static void assertStringEquals(String expected, String result) {
26     if (expected != null ? !expected.equals(result) : result != null) {
27       throw new Error("Expected: " + expected + ", found: " + result);
28     }
29   }
30 
assertClassEquals(Class<?> expected, Class<?> result)31   public static void assertClassEquals(Class<?> expected, Class<?> result) {
32     if (expected != result) {
33       throw new Error("Expected: " + expected + ", found: " + result);
34     }
35   }
36 
$noinline$foo(int x)37   private static int $noinline$foo(int x) {
38     return x;
39   }
40 
41   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: int Main.testSimple(int) builder (after)
42   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
43 
44   /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (before)
45   /// CHECK-NOT:            X86ComputeBaseMethodAddress
46 
47   /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after)
48   /// CHECK:                X86ComputeBaseMethodAddress
49   /// CHECK-NOT:            X86ComputeBaseMethodAddress
50 
testSimple(int x)51   public static int testSimple(int x) {
52     // This call should use PC-relative .bss array load to retrieve the target method.
53     return $noinline$foo(x);
54   }
55 
56   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: int Main.testSimpleAppImage(int) builder (after)
57   /// CHECK:                InvokeStaticOrDirect method_load_kind:AppImageRelRo
58 
59   /// CHECK-START-X86: int Main.testSimpleAppImage(int) pc_relative_fixups_x86 (before)
60   /// CHECK-NOT:            X86ComputeBaseMethodAddress
61 
62   /// CHECK-START-X86: int Main.testSimpleAppImage(int) pc_relative_fixups_x86 (after)
63   /// CHECK:                X86ComputeBaseMethodAddress
64   /// CHECK-NOT:            X86ComputeBaseMethodAddress
65 
testSimpleAppImage(int x)66   public static int testSimpleAppImage(int x) {
67     // This call should use PC-relative .data.img.rel.ro array load to retrieve the target method.
68     return AppImageClass.$noinline$foo(x);
69   }
70 
71   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: int Main.testDiamond(boolean, int) builder (after)
72   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
73   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
74 
75   /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (before)
76   /// CHECK-NOT:            X86ComputeBaseMethodAddress
77 
78   /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
79   /// CHECK:                X86ComputeBaseMethodAddress
80   /// CHECK-NOT:            X86ComputeBaseMethodAddress
81 
82   /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
83   /// CHECK:                X86ComputeBaseMethodAddress
84   /// CHECK-NEXT:           If
85 
testDiamond(boolean negate, int x)86   public static int testDiamond(boolean negate, int x) {
87     // These calls should use PC-relative loads to retrieve the target method.
88     // PC-relative bases used by X86 should be pulled before the If.
89     if (negate) {
90       return $noinline$foo(-x);
91     } else {
92       return $noinline$foo(x);
93     }
94   }
95 
96   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (before)
97   /// CHECK-NOT:            X86ComputeBaseMethodAddress
98 
99   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
100   /// CHECK:                X86ComputeBaseMethodAddress
101   /// CHECK-NOT:            X86ComputeBaseMethodAddress
102 
103   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
104   /// CHECK:                InvokeStaticOrDirect
105   /// CHECK-NOT:            InvokeStaticOrDirect
106 
107   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
108   /// CHECK:                ArrayLength
109   /// CHECK-NEXT:           X86ComputeBaseMethodAddress
110   /// CHECK-NEXT:           Goto
111   /// CHECK:                begin_block
112   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
113 
testLoop(int[] array, int x)114   public static int testLoop(int[] array, int x) {
115     // PC-relative bases used by X86 should be pulled before the loop.
116     for (int i : array) {
117       x += $noinline$foo(i);
118     }
119     return x;
120   }
121 
122   /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (before)
123   /// CHECK-NOT:            X86ComputeBaseMethodAddress
124 
125   /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (after)
126   /// CHECK:                If
127   /// CHECK:                begin_block
128   /// CHECK:                ArrayLength
129   /// CHECK-NEXT:           X86ComputeBaseMethodAddress
130   /// CHECK-NEXT:           Goto
131 
testLoopWithDiamond(int[] array, boolean negate, int x)132   public static int testLoopWithDiamond(int[] array, boolean negate, int x) {
133     // PC-relative bases used by X86 should be pulled before the loop but not outside the if.
134     if (array != null) {
135       for (int i : array) {
136         if (negate) {
137           x += $noinline$foo(-i);
138         } else {
139           x += $noinline$foo(i);
140         }
141       }
142     }
143     return x;
144   }
145 
146   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.String Main.$noinline$getBootImageString() builder (after)
147   /// CHECK:                LoadString load_kind:BootImageRelRo
148 
$noinline$getBootImageString()149   public static String $noinline$getBootImageString() {
150     // Empty string is known to be in the boot image.
151     return "";
152   }
153 
154   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.String Main.$noinline$getNonBootImageString() builder (after)
155   /// CHECK:                LoadString load_kind:BssEntry
156 
157   /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (before)
158   /// CHECK-NOT:            X86ComputeBaseMethodAddress
159 
160   /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (after)
161   /// CHECK-DAG:            X86ComputeBaseMethodAddress
162   /// CHECK-DAG:            LoadString load_kind:BssEntry
163 
$noinline$getNonBootImageString()164   public static String $noinline$getNonBootImageString() {
165     // This string is not in the boot image.
166     return "non-boot-image-string";
167   }
168 
169   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.Class Main.$noinline$getStringClass() builder (after)
170   /// CHECK:                LoadClass load_kind:BootImageRelRo class_name:java.lang.String
171 
$noinline$getStringClass()172   public static Class<?> $noinline$getStringClass() {
173     // String class is known to be in the boot image.
174     return String.class;
175   }
176 
177   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.Class Main.$noinline$getOtherClass() builder (after)
178   /// CHECK:                LoadClass load_kind:BssEntry class_name:Other
179 
180   /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (before)
181   /// CHECK-NOT:            X86ComputeBaseMethodAddress
182 
183   /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (after)
184   /// CHECK-DAG:            X86ComputeBaseMethodAddress
185   /// CHECK-DAG:            LoadClass load_kind:BssEntry class_name:Other
186 
$noinline$getOtherClass()187   public static Class<?> $noinline$getOtherClass() {
188     // Other class is neither in the boot image nor in the app image.
189     return Other.class;
190   }
191 
192   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.Class Main.$noinline$getAppImageClass() builder (after)
193   /// CHECK:                LoadClass load_kind:AppImageRelRo class_name:AppImageClass
194 
195   /// CHECK-START-X86: java.lang.Class Main.$noinline$getAppImageClass() pc_relative_fixups_x86 (before)
196   /// CHECK-NOT:            X86ComputeBaseMethodAddress
197 
198   /// CHECK-START-X86: java.lang.Class Main.$noinline$getAppImageClass() pc_relative_fixups_x86 (after)
199   /// CHECK-DAG:            X86ComputeBaseMethodAddress
200   /// CHECK-DAG:            LoadClass load_kind:AppImageRelRo class_name:AppImageClass
201 
$noinline$getAppImageClass()202   public static Class<?> $noinline$getAppImageClass() {
203     // AppImageClass class is in the app image.
204     return AppImageClass.class;
205   }
206 
207   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.String Main.$noinline$toHexString(int) builder (after)
208   /// CHECK:                InvokeStaticOrDirect method_load_kind:BootImageRelRo
$noinline$toHexString(int value)209   public static String $noinline$toHexString(int value) {
210     return Integer.toString(value, 16);
211   }
212 
213   /// CHECK-START-{ARM,ARM64,X86,X86_64,RISCV64}: java.lang.String Main.$noinline$toHexStringIndirect(int) builder (after)
214   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
215 
216   /// CHECK-START-X86: java.lang.String Main.$noinline$toHexStringIndirect(int) pc_relative_fixups_x86 (before)
217   /// CHECK-NOT:            X86ComputeBaseMethodAddress
218 
219   /// CHECK-START-X86: java.lang.String Main.$noinline$toHexStringIndirect(int) pc_relative_fixups_x86 (after)
220   /// CHECK-DAG:            X86ComputeBaseMethodAddress
221   /// CHECK-DAG:            InvokeStaticOrDirect method_load_kind:BssEntry
$noinline$toHexStringIndirect(int value)222   public static String $noinline$toHexStringIndirect(int value) {
223     return $noinline$toHexString(value);
224   }
225 
main(String[] args)226   public static void main(String[] args) {
227     assertIntEquals(1, testSimple(1));
228     assertIntEquals(1, testSimpleAppImage(1));
229     assertIntEquals(1, testDiamond(false, 1));
230     assertIntEquals(-1, testDiamond(true, 1));
231     assertIntEquals(3, testLoop(new int[]{ 2 }, 1));
232     assertIntEquals(8, testLoop(new int[]{ 3, 4 }, 1));
233     assertIntEquals(1, testLoopWithDiamond(null, false, 1));
234     assertIntEquals(3, testLoopWithDiamond(new int[]{ 2 }, false, 1));
235     assertIntEquals(-6, testLoopWithDiamond(new int[]{ 3, 4 }, true, 1));
236     assertStringEquals("", $noinline$getBootImageString());
237     assertStringEquals("non-boot-image-string", $noinline$getNonBootImageString());
238     assertClassEquals(String.class, $noinline$getStringClass());
239     assertClassEquals(Other.class, $noinline$getOtherClass());
240     assertStringEquals("12345678", $noinline$toHexString(0x12345678));
241     assertStringEquals("76543210", $noinline$toHexStringIndirect(0x76543210));
242   }
243 }
244 
245 class AppImageClass {
$noinline$foo(int x)246   public static int $noinline$foo(int x) {
247     return x;
248   }
249 }
250 
251 class Other {
252 }
253 
254 class MainExtension extends Main {
255 }
256