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