• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37   public static boolean doThrow = false;
38 
$noinline$foo(int x)39   private static int $noinline$foo(int x) {
40     if (doThrow) { throw new Error(); }
41     return x;
42   }
43 
44   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: int Main.testSimple(int) builder (after)
45   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
46 
47   /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (before)
48   /// CHECK-NOT:            X86ComputeBaseMethodAddress
49 
50   /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after)
51   /// CHECK:                X86ComputeBaseMethodAddress
52   /// CHECK-NOT:            X86ComputeBaseMethodAddress
53 
testSimple(int x)54   public static int testSimple(int x) {
55     // This call should use PC-relative .bss array load to retrieve the target method.
56     return $noinline$foo(x);
57   }
58 
59   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: int Main.testDiamond(boolean, int) builder (after)
60   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
61   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
62 
63   /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (before)
64   /// CHECK-NOT:            X86ComputeBaseMethodAddress
65 
66   /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
67   /// CHECK:                X86ComputeBaseMethodAddress
68   /// CHECK-NOT:            X86ComputeBaseMethodAddress
69 
70   /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
71   /// CHECK:                X86ComputeBaseMethodAddress
72   /// CHECK-NEXT:           If
73 
testDiamond(boolean negate, int x)74   public static int testDiamond(boolean negate, int x) {
75     // These calls should use PC-relative loads to retrieve the target method.
76     // PC-relative bases used by MIPS32R2 and X86 should be pulled before the If.
77     if (negate) {
78       return $noinline$foo(-x);
79     } else {
80       return $noinline$foo(x);
81     }
82   }
83 
84   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (before)
85   /// CHECK-NOT:            X86ComputeBaseMethodAddress
86 
87   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
88   /// CHECK:                X86ComputeBaseMethodAddress
89   /// CHECK-NOT:            X86ComputeBaseMethodAddress
90 
91   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
92   /// CHECK:                InvokeStaticOrDirect
93   /// CHECK-NOT:            InvokeStaticOrDirect
94 
95   /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
96   /// CHECK:                ArrayLength
97   /// CHECK-NEXT:           X86ComputeBaseMethodAddress
98   /// CHECK-NEXT:           Goto
99   /// CHECK:                begin_block
100   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
101 
testLoop(int[] array, int x)102   public static int testLoop(int[] array, int x) {
103     // PC-relative bases used by MIPS32R2 and X86 should be pulled before the loop.
104     for (int i : array) {
105       x += $noinline$foo(i);
106     }
107     return x;
108   }
109 
110   /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (before)
111   /// CHECK-NOT:            X86ComputeBaseMethodAddress
112 
113   /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (after)
114   /// CHECK:                If
115   /// CHECK:                begin_block
116   /// CHECK:                ArrayLength
117   /// CHECK-NEXT:           X86ComputeBaseMethodAddress
118   /// CHECK-NEXT:           Goto
119 
testLoopWithDiamond(int[] array, boolean negate, int x)120   public static int testLoopWithDiamond(int[] array, boolean negate, int x) {
121     // PC-relative bases used by MIPS32R2 and X86 should be pulled before the loop
122     // but not outside the if.
123     if (array != null) {
124       for (int i : array) {
125         if (negate) {
126           x += $noinline$foo(-i);
127         } else {
128           x += $noinline$foo(i);
129         }
130       }
131     }
132     return x;
133   }
134 
135   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.String Main.$noinline$getBootImageString() builder (after)
136   /// CHECK:                LoadString load_kind:BootImageRelRo
137 
$noinline$getBootImageString()138   public static String $noinline$getBootImageString() {
139     // Prevent inlining to avoid the string comparison being optimized away.
140     if (doThrow) { throw new Error(); }
141     // Empty string is known to be in the boot image.
142     return "";
143   }
144 
145   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.String Main.$noinline$getNonBootImageString() builder (after)
146   /// CHECK:                LoadString load_kind:BssEntry
147 
148   /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (before)
149   /// CHECK-NOT:            X86ComputeBaseMethodAddress
150 
151   /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (after)
152   /// CHECK-DAG:            X86ComputeBaseMethodAddress
153   /// CHECK-DAG:            LoadString load_kind:BssEntry
154 
$noinline$getNonBootImageString()155   public static String $noinline$getNonBootImageString() {
156     // Prevent inlining to avoid the string comparison being optimized away.
157     if (doThrow) { throw new Error(); }
158     // This string is not in the boot image.
159     return "non-boot-image-string";
160   }
161 
162   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.Class Main.$noinline$getStringClass() builder (after)
163   /// CHECK:                LoadClass load_kind:BootImageRelRo class_name:java.lang.String
164 
$noinline$getStringClass()165   public static Class<?> $noinline$getStringClass() {
166     // Prevent inlining to avoid the string comparison being optimized away.
167     if (doThrow) { throw new Error(); }
168     // String class is known to be in the boot image.
169     return String.class;
170   }
171 
172   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.Class Main.$noinline$getOtherClass() builder (after)
173   /// CHECK:                LoadClass load_kind:BssEntry class_name:Other
174 
175   /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (before)
176   /// CHECK-NOT:            X86ComputeBaseMethodAddress
177 
178   /// CHECK-START-X86: java.lang.Class Main.$noinline$getOtherClass() pc_relative_fixups_x86 (after)
179   /// CHECK-DAG:            X86ComputeBaseMethodAddress
180   /// CHECK-DAG:            LoadClass load_kind:BssEntry class_name:Other
181 
$noinline$getOtherClass()182   public static Class<?> $noinline$getOtherClass() {
183     // Prevent inlining to avoid the string comparison being optimized away.
184     if (doThrow) { throw new Error(); }
185     // Other class is not in the boot image.
186     return Other.class;
187   }
188 
189   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.String Main.$noinline$toHexString(int) builder (after)
190   /// CHECK:                InvokeStaticOrDirect method_load_kind:BootImageRelRo
$noinline$toHexString(int value)191   public static String $noinline$toHexString(int value) {
192     return Integer.toString(value, 16);
193   }
194 
195   /// CHECK-START-{ARM,ARM64,MIPS,MIPS64,X86,X86_64}: java.lang.String Main.$noinline$toHexStringIndirect(int) builder (after)
196   /// CHECK:                InvokeStaticOrDirect method_load_kind:BssEntry
197 
198   /// CHECK-START-X86: java.lang.String Main.$noinline$toHexStringIndirect(int) pc_relative_fixups_x86 (before)
199   /// CHECK-NOT:            X86ComputeBaseMethodAddress
200 
201   /// CHECK-START-X86: java.lang.String Main.$noinline$toHexStringIndirect(int) pc_relative_fixups_x86 (after)
202   /// CHECK-DAG:            X86ComputeBaseMethodAddress
203   /// CHECK-DAG:            InvokeStaticOrDirect method_load_kind:BssEntry
$noinline$toHexStringIndirect(int value)204   public static String $noinline$toHexStringIndirect(int value) {
205     return $noinline$toHexString(value);
206   }
207 
main(String[] args)208   public static void main(String[] args) {
209     assertIntEquals(1, testSimple(1));
210     assertIntEquals(1, testDiamond(false, 1));
211     assertIntEquals(-1, testDiamond(true, 1));
212     assertIntEquals(3, testLoop(new int[]{ 2 }, 1));
213     assertIntEquals(8, testLoop(new int[]{ 3, 4 }, 1));
214     assertIntEquals(1, testLoopWithDiamond(null, false, 1));
215     assertIntEquals(3, testLoopWithDiamond(new int[]{ 2 }, false, 1));
216     assertIntEquals(-6, testLoopWithDiamond(new int[]{ 3, 4 }, true, 1));
217     assertStringEquals("", $noinline$getBootImageString());
218     assertStringEquals("non-boot-image-string", $noinline$getNonBootImageString());
219     assertClassEquals(String.class, $noinline$getStringClass());
220     assertClassEquals(Other.class, $noinline$getOtherClass());
221     assertStringEquals("12345678", $noinline$toHexString(0x12345678));
222     assertStringEquals("76543210", $noinline$toHexStringIndirect(0x76543210));
223   }
224 }
225 
226 class Other {
227 }
228