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 // Add a class that will be the first entry in the dex cache, to
18 // avoid having the OtherDex and Main classes share the same cache index.
19 class AAA {
20 }
21 
22 public class Main {
23 
24   /// CHECK-START: void Main.inlineEmptyMethod() inliner (before)
25   /// CHECK-DAG:     <<Invoke:v\d+>>  InvokeStaticOrDirect
26   /// CHECK-DAG:                      ReturnVoid
27 
28   /// CHECK-START: void Main.inlineEmptyMethod() inliner (after)
29   /// CHECK-NOT:                      InvokeStaticOrDirect
30 
inlineEmptyMethod()31   public static void inlineEmptyMethod() {
32     OtherDex.emptyMethod();
33   }
34 
35   /// CHECK-START: int Main.inlineReturnIntMethod() inliner (before)
36   /// CHECK-DAG:     <<Invoke:i\d+>>  InvokeStaticOrDirect
37   /// CHECK-DAG:                      Return [<<Invoke>>]
38 
39   /// CHECK-START: int Main.inlineReturnIntMethod() inliner (after)
40   /// CHECK-NOT:                      InvokeStaticOrDirect
41 
42   /// CHECK-START: int Main.inlineReturnIntMethod() inliner (after)
43   /// CHECK-DAG:     <<Const38:i\d+>> IntConstant 38
44   /// CHECK-DAG:                      Return [<<Const38>>]
45 
inlineReturnIntMethod()46   public static int inlineReturnIntMethod() {
47     return OtherDex.returnIntMethod();
48   }
49 
50   /// CHECK-START: int Main.dontInlineOtherDexStatic() inliner (before)
51   /// CHECK-DAG:     <<Invoke:i\d+>>  InvokeStaticOrDirect
52   /// CHECK-DAG:                      Return [<<Invoke>>]
53 
54   /// CHECK-START: int Main.dontInlineOtherDexStatic() inliner (after)
55   /// CHECK-DAG:     <<Invoke:i\d+>>  InvokeStaticOrDirect
56   /// CHECK-DAG:                      Return [<<Invoke>>]
57 
dontInlineOtherDexStatic()58   public static int dontInlineOtherDexStatic() {
59     return OtherDex.returnOtherDexStatic();
60   }
61 
62   /// CHECK-START: int Main.inlineMainStatic() inliner (before)
63   /// CHECK-DAG:     <<Invoke:i\d+>>  InvokeStaticOrDirect
64   /// CHECK-DAG:                      Return [<<Invoke>>]
65 
66   /// CHECK-START: int Main.inlineMainStatic() inliner (after)
67   /// CHECK-NOT:                      InvokeStaticOrDirect
68 
69   /// CHECK-START: int Main.inlineMainStatic() inliner (after)
70   /// CHECK-DAG:     <<Static:i\d+>>  StaticFieldGet
71   /// CHECK-DAG:                      Return [<<Static>>]
72 
inlineMainStatic()73   public static int inlineMainStatic() {
74     return OtherDex.returnMainStatic();
75   }
76 
77   /// CHECK-START: int Main.dontInlineRecursiveCall() inliner (before)
78   /// CHECK-DAG:     <<Invoke:i\d+>>  InvokeStaticOrDirect
79   /// CHECK-DAG:                      Return [<<Invoke>>]
80 
81   /// CHECK-START: int Main.dontInlineRecursiveCall() inliner (after)
82   /// CHECK-DAG:     <<Invoke:i\d+>>  InvokeStaticOrDirect
83   /// CHECK-DAG:                      Return [<<Invoke>>]
84 
dontInlineRecursiveCall()85   public static int dontInlineRecursiveCall() {
86     return OtherDex.recursiveCall();
87   }
88 
89   /// CHECK-START: java.lang.String Main.dontInlineReturnString() inliner (before)
90   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
91   /// CHECK-DAG:                      Return [<<Invoke>>]
92 
93   /// CHECK-START: java.lang.String Main.dontInlineReturnString() inliner (after)
94   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
95   /// CHECK-DAG:                      Return [<<Invoke>>]
96 
dontInlineReturnString()97   public static String dontInlineReturnString() {
98     return OtherDex.returnString();
99   }
100 
101   /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClass() inliner (before)
102   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
103   /// CHECK-DAG:                      Return [<<Invoke>>]
104 
105   /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClass() inliner (after)
106   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
107   /// CHECK-DAG:                      Return [<<Invoke>>]
108 
dontInlineOtherDexClass()109   public static Class<?> dontInlineOtherDexClass() {
110     return OtherDex.returnOtherDexClass();
111   }
112 
113   /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (before)
114   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
115   /// CHECK-DAG:                      Return [<<Invoke>>]
116 
117   /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after)
118   /// CHECK-NOT:                      InvokeStaticOrDirect
119 
120   /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after)
121   /// CHECK-DAG:                     Return [<<Class:l\d+>>]
122   /// CHECK-DAG:     <<Class>>       LoadClass
123   // Note: There are two LoadClass instructions. We obtain the correct
124   //       instruction id by matching the Return's input list first.
125 
inlineMainClass()126   public static Class<?> inlineMainClass() {
127     return OtherDex.returnMainClass();
128   }
129 
130   /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClassStaticCall() inliner (before)
131   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
132   /// CHECK-DAG:                      Return [<<Invoke>>]
133 
134   /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClassStaticCall() inliner (after)
135   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
136   /// CHECK-DAG:                      Return [<<Invoke>>]
137 
dontInlineOtherDexClassStaticCall()138   public static Class<?> dontInlineOtherDexClassStaticCall() {
139     return OtherDex.returnOtherDexClassStaticCall();
140   }
141 
142   /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (before)
143   /// CHECK-DAG:     <<Invoke:l\d+>>  InvokeStaticOrDirect
144   /// CHECK-DAG:                      Return [<<Invoke>>]
145 
146   /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after)
147   /// CHECK-NOT:                      InvokeStaticOrDirect
148 
149   /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after)
150   /// CHECK-DAG:                     Return [<<Class:l\d+>>]
151   /// CHECK-DAG:     <<Class>>       LoadClass
152   // Note: There are two LoadClass instructions. We obtain the correct
153   //       instruction id by matching the Return's input list first.
154 
inlineOtherDexCallingMain()155   public static Class<?> inlineOtherDexCallingMain() {
156     return OtherDex.returnOtherDexCallingMain();
157   }
158 
getOtherClass()159   public static Class<?> getOtherClass() {
160     return Main.class;
161   }
162 
main(String[] args)163   public static void main(String[] args) {
164     inlineEmptyMethod();
165     if (inlineReturnIntMethod() != 38) {
166       throw new Error("Expected 38");
167     }
168 
169     if (dontInlineOtherDexStatic() != 1) {
170       throw new Error("Expected 1");
171     }
172 
173     if (inlineMainStatic() != 42) {
174       throw new Error("Expected 42");
175     }
176 
177     if (dontInlineReturnString() != "OtherDex") {
178       throw new Error("Expected OtherDex");
179     }
180 
181     if (dontInlineOtherDexClass() != OtherDex.class) {
182       throw new Error("Expected " + OtherDex.class);
183     }
184 
185     if (dontInlineOtherDexClassStaticCall() != OtherDex.class) {
186       throw new Error("Expected " + OtherDex.class);
187     }
188 
189     if (inlineMainClass() != Main.class) {
190       throw new Error("Expected " + Main.class);
191     }
192 
193     if (inlineOtherDexCallingMain() != Main.class) {
194       throw new Error("Expected " + Main.class);
195     }
196   }
197 
198   // Reference the AAA class to ensure it is in the dex cache.
199   public static Class<?> cls = AAA.class;
200 
201   // Add a field that will be the first entry in the dex cache, to
202   // avoid having the OtherDex.myStatic and Main.myStatic fields
203   // share the same cache index.
204   public static int aaa = 32;
205   public static int myStatic = 42;
206 }
207