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