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