blob: 3d985bfaf099559104cdc33ba9611a3b7c468632 [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 Markof64242a2015-12-01 14:58:23 +000031 public static boolean doThrow = false;
32
33 private static int $noinline$foo(int x) {
34 if (doThrow) { throw new Error(); }
35 return x;
36 }
37
38 /// CHECK-START: int Main.testSimple(int) sharpening (before)
39 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_via_method
40
41 /// CHECK-START-ARM: int Main.testSimple(int) sharpening (after)
42 /// CHECK-NOT: ArmDexCacheArraysBase
43 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
44
45 /// CHECK-START-ARM64: int Main.testSimple(int) sharpening (after)
46 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
47
48 /// CHECK-START-X86: int Main.testSimple(int) sharpening (after)
49 /// CHECK-NOT: X86ComputeBaseMethodAddress
50 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
51
52 /// CHECK-START-X86_64: int Main.testSimple(int) sharpening (after)
53 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
54
55 /// CHECK-START-ARM: int Main.testSimple(int) dex_cache_array_fixups_arm (after)
56 /// CHECK: ArmDexCacheArraysBase
57 /// CHECK-NOT: ArmDexCacheArraysBase
58
59 /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after)
60 /// CHECK: X86ComputeBaseMethodAddress
61 /// CHECK-NOT: X86ComputeBaseMethodAddress
62
63 public static int testSimple(int x) {
64 // This call should use PC-relative dex cache array load to retrieve the target method.
65 return $noinline$foo(x);
66 }
67
68 /// CHECK-START: int Main.testDiamond(boolean, int) sharpening (before)
69 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_via_method
70
71 /// CHECK-START-ARM: int Main.testDiamond(boolean, int) sharpening (after)
72 /// CHECK-NOT: ArmDexCacheArraysBase
73 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
74 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
75
76 /// CHECK-START-ARM64: int Main.testDiamond(boolean, int) sharpening (after)
77 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
78 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
79
80 /// CHECK-START-X86: int Main.testDiamond(boolean, int) sharpening (after)
81 /// CHECK-NOT: X86ComputeBaseMethodAddress
82 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
83 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
84
85 /// CHECK-START-X86_64: int Main.testDiamond(boolean, int) sharpening (after)
86 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
87 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
88
89 /// CHECK-START-ARM: int Main.testDiamond(boolean, int) dex_cache_array_fixups_arm (after)
90 /// CHECK: ArmDexCacheArraysBase
91 /// CHECK-NOT: ArmDexCacheArraysBase
92
93 /// CHECK-START-ARM: int Main.testDiamond(boolean, int) dex_cache_array_fixups_arm (after)
94 /// CHECK: ArmDexCacheArraysBase
95 /// CHECK-NEXT: If
96
97 /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
98 /// CHECK: X86ComputeBaseMethodAddress
99 /// CHECK-NOT: X86ComputeBaseMethodAddress
100
101 /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
102 /// CHECK: X86ComputeBaseMethodAddress
103 /// CHECK-NEXT: If
104
105 public static int testDiamond(boolean negate, int x) {
106 // These calls should use PC-relative dex cache array loads to retrieve the target method.
107 // PC-relative bases used by X86 and ARM should be pulled before the If.
108 if (negate) {
109 return $noinline$foo(-x);
110 } else {
111 return $noinline$foo(x);
112 }
113 }
114
115 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (before)
116 /// CHECK-NOT: X86ComputeBaseMethodAddress
117
118 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
119 /// CHECK: X86ComputeBaseMethodAddress
120 /// CHECK-NOT: X86ComputeBaseMethodAddress
121
122 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
123 /// CHECK: InvokeStaticOrDirect
124 /// CHECK-NOT: InvokeStaticOrDirect
125
126 /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
127 /// CHECK: ArrayLength
128 /// CHECK-NEXT: X86ComputeBaseMethodAddress
129 /// CHECK-NEXT: Goto
130 /// CHECK: begin_block
131 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
132
133 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (before)
134 /// CHECK-NOT: ArmDexCacheArraysBase
135
136 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
137 /// CHECK: ArmDexCacheArraysBase
138 /// CHECK-NOT: ArmDexCacheArraysBase
139
140 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
141 /// CHECK: InvokeStaticOrDirect
142 /// CHECK-NOT: InvokeStaticOrDirect
143
144 /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
145 /// CHECK: ArrayLength
146 /// CHECK-NEXT: ArmDexCacheArraysBase
147 /// CHECK-NEXT: Goto
148 /// CHECK: begin_block
149 /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
150
151 public static int testLoop(int[] array, int x) {
152 // PC-relative bases used by X86 and ARM should be pulled before the loop.
153 for (int i : array) {
154 x += $noinline$foo(i);
155 }
156 return x;
157 }
158
159 /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (before)
160 /// CHECK-NOT: X86ComputeBaseMethodAddress
161
162 /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (after)
163 /// CHECK: If
164 /// CHECK: begin_block
165 /// CHECK: ArrayLength
166 /// CHECK-NEXT: X86ComputeBaseMethodAddress
167 /// CHECK-NEXT: Goto
168
169 /// CHECK-START-ARM: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_arm (before)
170 /// CHECK-NOT: ArmDexCacheArraysBase
171
172 /// CHECK-START-ARM: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_arm (after)
173 /// CHECK: If
174 /// CHECK: begin_block
175 /// CHECK: ArrayLength
176 /// CHECK-NEXT: ArmDexCacheArraysBase
177 /// CHECK-NEXT: Goto
178
179 public static int testLoopWithDiamond(int[] array, boolean negate, int x) {
180 // PC-relative bases used by X86 and ARM should be pulled before the loop
181 // but not outside the if.
182 if (array != null) {
183 for (int i : array) {
184 if (negate) {
185 x += $noinline$foo(-i);
186 } else {
187 x += $noinline$foo(i);
188 }
189 }
190 }
191 return x;
192 }
193
Vladimir Markocac5a7e2016-02-22 10:39:50 +0000194 /// CHECK-START: java.lang.String Main.$noinline$getBootImageString() sharpening (before)
195 /// CHECK: LoadString load_kind:DexCacheViaMethod
196
197 /// CHECK-START-X86: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
198 // Note: load kind depends on PIC/non-PIC
199 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
200 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
201
202 /// CHECK-START-X86_64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
203 // Note: load kind depends on PIC/non-PIC
204 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
205 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
206
207 /// CHECK-START-ARM: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
208 // Note: load kind depends on PIC/non-PIC
209 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
210 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
211
212 /// CHECK-START-ARM64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
213 // Note: load kind depends on PIC/non-PIC
214 // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
215 /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
216
217 public static String $noinline$getBootImageString() {
218 // Prevent inlining to avoid the string comparison being optimized away.
219 if (doThrow) { throw new Error(); }
220 // Empty string is known to be in the boot image.
221 return "";
222 }
223
224 /// CHECK-START: java.lang.String Main.$noinline$getNonBootImageString() sharpening (before)
225 /// CHECK: LoadString load_kind:DexCacheViaMethod
226
227 /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
228 /// CHECK: LoadString load_kind:DexCachePcRelative
229
230 /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (after)
231 /// CHECK-DAG: X86ComputeBaseMethodAddress
232 /// CHECK-DAG: LoadString load_kind:DexCachePcRelative
233
234 /// CHECK-START-X86_64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
235 /// CHECK: LoadString load_kind:DexCachePcRelative
236
237 /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
238 /// CHECK: LoadString load_kind:DexCachePcRelative
239
240 /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() dex_cache_array_fixups_arm (after)
241 /// CHECK-DAG: ArmDexCacheArraysBase
242 /// CHECK-DAG: LoadString load_kind:DexCachePcRelative
243
244 /// CHECK-START-ARM64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
245 /// CHECK: LoadString load_kind:DexCachePcRelative
246
247 public static String $noinline$getNonBootImageString() {
248 // Prevent inlining to avoid the string comparison being optimized away.
249 if (doThrow) { throw new Error(); }
250 // This string is not in the boot image.
251 return "non-boot-image-string";
252 }
253
Vladimir Markof64242a2015-12-01 14:58:23 +0000254 public static void main(String[] args) {
255 assertIntEquals(1, testSimple(1));
256 assertIntEquals(1, testDiamond(false, 1));
257 assertIntEquals(-1, testDiamond(true, 1));
258 assertIntEquals(3, testLoop(new int[]{ 2 }, 1));
259 assertIntEquals(8, testLoop(new int[]{ 3, 4 }, 1));
260 assertIntEquals(1, testLoopWithDiamond(null, false, 1));
261 assertIntEquals(3, testLoopWithDiamond(new int[]{ 2 }, false, 1));
262 assertIntEquals(-6, testLoopWithDiamond(new int[]{ 3, 4 }, true, 1));
Vladimir Markocac5a7e2016-02-22 10:39:50 +0000263 assertStringEquals("", $noinline$getBootImageString());
264 assertStringEquals("non-boot-image-string", $noinline$getNonBootImageString());
Vladimir Markof64242a2015-12-01 14:58:23 +0000265 }
266}