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