blob: 09a77ed285c663f529f9f2a4f79e0b0871b61f97 [file] [log] [blame]
Vladimir Markof64242a2015-12-01 14:58:23 +00001/*
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
17public class Main {
18
19 public static void assertIntEquals(int expected, int result) {
20 if (expected != result) {
21 throw new Error("Expected: " + expected + ", found: " + result);
22 }
23 }
24
Vladimir Markocac5a7e2016-02-22 10:39:50 +000025 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
Vladimir Markodbb7f5b2016-03-30 13:23:58 +010031 public static void assertClassEquals(Class<?> expected, Class<?> result) {
32 if (expected != result) {
33 throw new Error("Expected: " + expected + ", found: " + result);
34 }
35 }
36
Vladimir Markof64242a2015-12-01 14:58:23 +000037 public static boolean doThrow = false;
38
39 private static int $noinline$foo(int x) {
40 if (doThrow) { throw new Error(); }
41 return x;
42 }
43
44 /// CHECK-START: int Main.testSimple(int) sharpening (before)
45 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_via_method
46
47 /// CHECK-START-ARM: int Main.testSimple(int) sharpening (after)
48 /// CHECK-NOT: ArmDexCacheArraysBase
49 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
50
51 /// CHECK-START-ARM64: int Main.testSimple(int) sharpening (after)
52 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
53
54 /// CHECK-START-X86: int Main.testSimple(int) sharpening (after)
55 /// CHECK-NOT: X86ComputeBaseMethodAddress
56 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
57
58 /// CHECK-START-X86_64: int Main.testSimple(int) sharpening (after)
59 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
60
61 /// CHECK-START-ARM: int Main.testSimple(int) dex_cache_array_fixups_arm (after)
62 /// CHECK: ArmDexCacheArraysBase
63 /// CHECK-NOT: ArmDexCacheArraysBase
64
65 /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after)
66 /// CHECK: X86ComputeBaseMethodAddress
67 /// CHECK-NOT: X86ComputeBaseMethodAddress
68
69 public static int testSimple(int x) {
70 // This call should use PC-relative dex cache array load to retrieve the target method.
71 return $noinline$foo(x);
72 }
73
74 /// CHECK-START: int Main.testDiamond(boolean, int) sharpening (before)
75 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_via_method
76
77 /// CHECK-START-ARM: int Main.testDiamond(boolean, int) sharpening (after)
78 /// CHECK-NOT: ArmDexCacheArraysBase
79 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
80 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
81
82 /// CHECK-START-ARM64: int Main.testDiamond(boolean, int) sharpening (after)
83 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
84 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
85
86 /// CHECK-START-X86: int Main.testDiamond(boolean, int) sharpening (after)
87 /// CHECK-NOT: X86ComputeBaseMethodAddress
88 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
89 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
90
91 /// CHECK-START-X86_64: int Main.testDiamond(boolean, int) sharpening (after)
92 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
93 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
94
95 /// CHECK-START-ARM: int Main.testDiamond(boolean, int) dex_cache_array_fixups_arm (after)
96 /// CHECK: ArmDexCacheArraysBase
97 /// CHECK-NOT: ArmDexCacheArraysBase
98
99 /// CHECK-START-ARM: int Main.testDiamond(boolean, int) dex_cache_array_fixups_arm (after)
100 /// CHECK: ArmDexCacheArraysBase
101 /// CHECK-NEXT: If
102
103 /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
104 /// CHECK: X86ComputeBaseMethodAddress
105 /// CHECK-NOT: X86ComputeBaseMethodAddress
106
107 /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
108 /// CHECK: X86ComputeBaseMethodAddress
109 /// CHECK-NEXT: If
110
111 public static int testDiamond(boolean negate, int x) {
112 // These calls should use PC-relative dex cache array loads to retrieve the target method.
113 // PC-relative bases used by X86 and ARM should be pulled before the If.
114 if (negate) {
115 return $noinline$foo(-x);
116 } else {
117 return $noinline$foo(x);
118 }
119 }
120
121 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (before)
122 /// CHECK-NOT: X86ComputeBaseMethodAddress
123
124 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
125 /// CHECK: X86ComputeBaseMethodAddress
126 /// CHECK-NOT: X86ComputeBaseMethodAddress
127
128 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
129 /// CHECK: InvokeStaticOrDirect
130 /// CHECK-NOT: InvokeStaticOrDirect
131
132 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
133 /// CHECK: ArrayLength
134 /// CHECK-NEXT: X86ComputeBaseMethodAddress
135 /// CHECK-NEXT: Goto
136 /// CHECK: begin_block
137 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
138
139 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (before)
140 /// CHECK-NOT: ArmDexCacheArraysBase
141
142 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
143 /// CHECK: ArmDexCacheArraysBase
144 /// CHECK-NOT: ArmDexCacheArraysBase
145
146 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
147 /// CHECK: InvokeStaticOrDirect
148 /// CHECK-NOT: InvokeStaticOrDirect
149
150 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
151 /// CHECK: ArrayLength
152 /// CHECK-NEXT: ArmDexCacheArraysBase
153 /// CHECK-NEXT: Goto
154 /// CHECK: begin_block
155 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
156
157 public static int testLoop(int[] array, int x) {
158 // PC-relative bases used by X86 and ARM should be pulled before the loop.
159 for (int i : array) {
160 x += $noinline$foo(i);
161 }
162 return x;
163 }
164
165 /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (before)
166 /// CHECK-NOT: X86ComputeBaseMethodAddress
167
168 /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (after)
169 /// CHECK: If
170 /// CHECK: begin_block
171 /// CHECK: ArrayLength
172 /// CHECK-NEXT: X86ComputeBaseMethodAddress
173 /// CHECK-NEXT: Goto
174
175 /// CHECK-START-ARM: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_arm (before)
176 /// CHECK-NOT: ArmDexCacheArraysBase
177
178 /// CHECK-START-ARM: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_arm (after)
179 /// CHECK: If
180 /// CHECK: begin_block
181 /// CHECK: ArrayLength
182 /// CHECK-NEXT: ArmDexCacheArraysBase
183 /// CHECK-NEXT: Goto
184
185 public static int testLoopWithDiamond(int[] array, boolean negate, int x) {
186 // PC-relative bases used by X86 and ARM should be pulled before the loop
187 // but not outside the if.
188 if (array != null) {
189 for (int i : array) {
190 if (negate) {
191 x += $noinline$foo(-i);
192 } else {
193 x += $noinline$foo(i);
194 }
195 }
196 }
197 return x;
198 }
199
Vladimir Markocac5a7e2016-02-22 10:39:50 +0000200 /// CHECK-START: java.lang.String Main.$noinline$getBootImageString() sharpening (before)
201 /// CHECK: LoadString load_kind:DexCacheViaMethod
202
203 /// CHECK-START-X86: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
204 // Note: load kind depends on PIC/non-PIC
205 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
206 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
207
208 /// CHECK-START-X86_64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
209 // Note: load kind depends on PIC/non-PIC
210 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
211 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
212
213 /// CHECK-START-ARM: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
214 // Note: load kind depends on PIC/non-PIC
215 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
216 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
217
218 /// CHECK-START-ARM64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
219 // Note: load kind depends on PIC/non-PIC
220 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
221 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
222
223 public static String $noinline$getBootImageString() {
224 // Prevent inlining to avoid the string comparison being optimized away.
225 if (doThrow) { throw new Error(); }
226 // Empty string is known to be in the boot image.
227 return "";
228 }
229
230 /// CHECK-START: java.lang.String Main.$noinline$getNonBootImageString() sharpening (before)
231 /// CHECK: LoadString load_kind:DexCacheViaMethod
232
233 /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
234 /// CHECK: LoadString load_kind:DexCachePcRelative
235
236 /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (after)
237 /// CHECK-DAG: X86ComputeBaseMethodAddress
238 /// CHECK-DAG: LoadString load_kind:DexCachePcRelative
239
240 /// CHECK-START-X86_64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
241 /// CHECK: LoadString load_kind:DexCachePcRelative
242
243 /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
244 /// CHECK: LoadString load_kind:DexCachePcRelative
245
246 /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() dex_cache_array_fixups_arm (after)
247 /// CHECK-DAG: ArmDexCacheArraysBase
248 /// CHECK-DAG: LoadString load_kind:DexCachePcRelative
249
250 /// CHECK-START-ARM64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
251 /// CHECK: LoadString load_kind:DexCachePcRelative
252
253 public static String $noinline$getNonBootImageString() {
254 // Prevent inlining to avoid the string comparison being optimized away.
255 if (doThrow) { throw new Error(); }
256 // This string is not in the boot image.
257 return "non-boot-image-string";
258 }
259
Vladimir Markodbb7f5b2016-03-30 13:23:58 +0100260 /// CHECK-START: java.lang.Class Main.$noinline$getStringClass() sharpening (before)
261 /// CHECK: LoadClass load_kind:DexCacheViaMethod class_name:java.lang.String
262
263 /// CHECK-START-X86: java.lang.Class Main.$noinline$getStringClass() sharpening (after)
264 // Note: load kind depends on PIC/non-PIC
265 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
266 /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String
267
268 /// CHECK-START-X86_64: java.lang.Class Main.$noinline$getStringClass() sharpening (after)
269 // Note: load kind depends on PIC/non-PIC
270 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
271 /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String
272
273 /// CHECK-START-ARM: java.lang.Class Main.$noinline$getStringClass() sharpening (after)
274 // Note: load kind depends on PIC/non-PIC
275 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
276 /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String
277
278 /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getStringClass() sharpening (after)
279 // Note: load kind depends on PIC/non-PIC
280 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
281 /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String
282
283 public static Class<?> $noinline$getStringClass() {
284 // Prevent inlining to avoid the string comparison being optimized away.
285 if (doThrow) { throw new Error(); }
286 // String class is known to be in the boot image.
287 return String.class;
288 }
289
290 /// CHECK-START: java.lang.Class Main.$noinline$getOtherClass() sharpening (before)
291 /// CHECK: LoadClass load_kind:DexCacheViaMethod class_name:Other
292
293 /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() sharpening (after)
294 /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other
295
296 /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (after)
297 /// CHECK-DAG: X86ComputeBaseMethodAddress
298 /// CHECK-DAG: LoadClass load_kind:DexCachePcRelative class_name:Other
299
300 /// CHECK-START-X86_64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after)
301 /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other
302
303 /// CHECK-START-ARM: java.lang.Class Main.$noinline$getOtherClass() sharpening (after)
304 /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other
305
306 /// CHECK-START-ARM: java.lang.Class Main.$noinline$getOtherClass() dex_cache_array_fixups_arm (after)
307 /// CHECK-DAG: ArmDexCacheArraysBase
308 /// CHECK-DAG: LoadClass load_kind:DexCachePcRelative class_name:Other
309
310 /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after)
311 /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other
312
313 public static Class<?> $noinline$getOtherClass() {
314 // Prevent inlining to avoid the string comparison being optimized away.
315 if (doThrow) { throw new Error(); }
316 // Other class is not in the boot image.
317 return Other.class;
318 }
319
Vladimir Markof64242a2015-12-01 14:58:23 +0000320 public static void main(String[] args) {
321 assertIntEquals(1, testSimple(1));
322 assertIntEquals(1, testDiamond(false, 1));
323 assertIntEquals(-1, testDiamond(true, 1));
324 assertIntEquals(3, testLoop(new int[]{ 2 }, 1));
325 assertIntEquals(8, testLoop(new int[]{ 3, 4 }, 1));
326 assertIntEquals(1, testLoopWithDiamond(null, false, 1));
327 assertIntEquals(3, testLoopWithDiamond(new int[]{ 2 }, false, 1));
328 assertIntEquals(-6, testLoopWithDiamond(new int[]{ 3, 4 }, true, 1));
Vladimir Markocac5a7e2016-02-22 10:39:50 +0000329 assertStringEquals("", $noinline$getBootImageString());
330 assertStringEquals("non-boot-image-string", $noinline$getNonBootImageString());
Vladimir Markodbb7f5b2016-03-30 13:23:58 +0100331 assertClassEquals(String.class, $noinline$getStringClass());
332 assertClassEquals(Other.class, $noinline$getOtherClass());
Vladimir Markof64242a2015-12-01 14:58:23 +0000333 }
334}
Vladimir Markodbb7f5b2016-03-30 13:23:58 +0100335
336class Other {
337}