1 /* 2 * Copyright (C) 2014 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 import java.lang.reflect.Method; 17 18 public class Main { 19 20 /// CHECK-START: void Main.InlineVoid() inliner (before) 21 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 22 /// CHECK-DAG: InvokeStaticOrDirect 23 /// CHECK-DAG: InvokeStaticOrDirect [<<Const42>>{{(,[ij]\d+)?}}] 24 25 /// CHECK-START: void Main.InlineVoid() inliner (after) 26 /// CHECK-NOT: InvokeStaticOrDirect 27 InlineVoid()28 public static void InlineVoid() { 29 returnVoid(); 30 returnVoidWithOneParameter(42); 31 } 32 33 /// CHECK-START: int Main.InlineParameter(int) inliner (before) 34 /// CHECK-DAG: <<Param:i\d+>> ParameterValue 35 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}] 36 /// CHECK-DAG: Return [<<Result>>] 37 38 /// CHECK-START: int Main.InlineParameter(int) inliner (after) 39 /// CHECK-DAG: <<Param:i\d+>> ParameterValue 40 /// CHECK-DAG: Return [<<Param>>] 41 InlineParameter(int a)42 public static int InlineParameter(int a) { 43 return returnParameter(a); 44 } 45 46 /// CHECK-START: long Main.InlineWideParameter(long) inliner (before) 47 /// CHECK-DAG: <<Param:j\d+>> ParameterValue 48 /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}] 49 /// CHECK-DAG: Return [<<Result>>] 50 51 /// CHECK-START: long Main.InlineWideParameter(long) inliner (after) 52 /// CHECK-DAG: <<Param:j\d+>> ParameterValue 53 /// CHECK-DAG: Return [<<Param>>] 54 InlineWideParameter(long a)55 public static long InlineWideParameter(long a) { 56 return returnWideParameter(a); 57 } 58 59 /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (before) 60 /// CHECK-DAG: <<Param:l\d+>> ParameterValue 61 /// CHECK-DAG: <<Result:l\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}] 62 /// CHECK-DAG: Return [<<Result>>] 63 64 /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (after) 65 /// CHECK-DAG: <<Param:l\d+>> ParameterValue 66 /// CHECK-DAG: Return [<<Param>>] 67 InlineReferenceParameter(Object o)68 public static Object InlineReferenceParameter(Object o) { 69 return returnReferenceParameter(o); 70 } 71 72 /// CHECK-START: int Main.InlineInt() inliner (before) 73 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 74 /// CHECK-DAG: Return [<<Result>>] 75 76 /// CHECK-START: int Main.InlineInt() inliner (after) 77 /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4 78 /// CHECK-DAG: Return [<<Const4>>] 79 InlineInt()80 public static int InlineInt() { 81 return returnInt(); 82 } 83 84 /// CHECK-START: long Main.InlineWide() inliner (before) 85 /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect 86 /// CHECK-DAG: Return [<<Result>>] 87 88 /// CHECK-START: long Main.InlineWide() inliner (after) 89 /// CHECK-DAG: <<Const8:j\d+>> LongConstant 8 90 /// CHECK-DAG: Return [<<Const8>>] 91 InlineWide()92 public static long InlineWide() { 93 return returnWide(); 94 } 95 96 /// CHECK-START: int Main.InlineAdd() inliner (before) 97 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 98 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 99 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 100 /// CHECK-DAG: Return [<<Result>>] 101 102 /// CHECK-START: int Main.InlineAdd() inliner (after) 103 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 104 /// CHECK-DAG: Return [<<Const8>>] 105 InlineAdd()106 public static int InlineAdd() { 107 return returnAdd(3, 5); 108 } 109 110 /// CHECK-START: int Main.InlineFieldAccess() inliner (before) 111 /// CHECK-DAG: <<After:i\d+>> InvokeStaticOrDirect 112 /// CHECK-DAG: Return [<<After>>] 113 114 /// CHECK-START: int Main.InlineFieldAccess() inliner (after) 115 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 116 /// CHECK-DAG: <<Before:i\d+>> StaticFieldGet 117 /// CHECK-DAG: <<After:i\d+>> Add [<<Before>>,<<Const1>>] 118 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<After>>] 119 /// CHECK-DAG: Return [<<After>>] 120 121 /// CHECK-START: int Main.InlineFieldAccess() inliner (after) 122 /// CHECK-NOT: InvokeStaticOrDirect 123 InlineFieldAccess()124 public static int InlineFieldAccess() { 125 return incCounter(); 126 } 127 InlineWithControlFlow(boolean cond)128 public static int InlineWithControlFlow(boolean cond) { 129 try { 130 Class<?> c = Class.forName("Smali"); 131 Method m = c.getMethod("InlineWithControlFlow", boolean.class); 132 return (Integer) m.invoke(null, cond); 133 } catch (Throwable t) { 134 throw new RuntimeException(t); 135 } 136 } 137 138 /// CHECK-START: int Main.returnAbs(int) intrinsics_recognition (before) 139 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 140 /// CHECK-DAG: Return [<<Result>>] 141 142 /// CHECK-START: int Main.returnAbs(int) intrinsics_recognition (after) 143 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:MathAbsInt 144 /// CHECK-DAG: Return [<<Result>>] 145 returnAbs(int i)146 private static int returnAbs(int i) { 147 return Math.abs(i); 148 } 149 150 /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (before) 151 /// CHECK-DAG: <<ConstMinus1:i\d+>> IntConstant -1 152 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect 153 /// CHECK-DAG: Return [<<Result>>] 154 155 /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (after) 156 /// CHECK-DAG: <<ConstMinus1:i\d+>> IntConstant -1 157 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:MathAbsInt 158 /// CHECK-DAG: Return [<<Result>>] 159 InlinedIntrinsicsAreStillIntrinsic()160 public static int InlinedIntrinsicsAreStillIntrinsic() { 161 return returnAbs(-1); 162 } 163 returnVoid()164 private static void returnVoid() { 165 return; 166 } 167 returnVoidWithOneParameter(int a)168 private static void returnVoidWithOneParameter(int a) { 169 return; 170 } 171 returnParameter(int a)172 private static int returnParameter(int a) { 173 return a; 174 } 175 returnWideParameter(long a)176 private static long returnWideParameter(long a) { 177 return a; 178 } 179 returnReferenceParameter(Object o)180 private static Object returnReferenceParameter(Object o) { 181 return o; 182 } 183 returnInt()184 private static int returnInt() { 185 return 4; 186 } 187 returnWide()188 private static long returnWide() { 189 return 8L; 190 } 191 returnAdd(int a, int b)192 private static int returnAdd(int a, int b) { 193 return a + b; 194 } 195 returnSub(int a, int b)196 private static int returnSub(int a, int b) { 197 return a - b; 198 } 199 200 private static int counter = 42; 201 incCounter()202 private static int incCounter() { 203 return ++counter; 204 } 205 main(String[] args)206 public static void main(String[] args) { 207 InlineVoid(); 208 209 if (InlineInt() != 4) { 210 throw new Error(); 211 } 212 213 if (InlineWide() != 8L) { 214 throw new Error(); 215 } 216 217 if (InlineParameter(42) != 42) { 218 throw new Error(); 219 } 220 221 if (InlineWideParameter(0x100000001L) != 0x100000001L) { 222 throw new Error(); 223 } 224 225 if (InlineReferenceParameter(Main.class) != Main.class) { 226 throw new Error(); 227 } 228 229 if (InlineAdd() != 8) { 230 throw new Error(); 231 } 232 233 if (InlineFieldAccess() != 43 || InlineFieldAccess() != 44) { 234 throw new Error(); 235 } 236 237 if (InlineWithControlFlow(true) != 4) { 238 throw new Error(); 239 } 240 241 if (InlineWithControlFlow(false) != 2) { 242 throw new Error(); 243 } 244 245 if (InlinedIntrinsicsAreStillIntrinsic() != 1) { 246 throw new Error(); 247 } 248 249 if (returnAbs(-1) != 1) { 250 throw new Error(); 251 } 252 } 253 } 254