1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker // Add a class that will be the first entry in the dex cache, to 18*795d594fSAndroid Build Coastguard Worker // avoid having the OtherDex and Main classes share the same cache index. 19*795d594fSAndroid Build Coastguard Worker class AAA { 20*795d594fSAndroid Build Coastguard Worker } 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker public class Main { 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inlineEmptyMethod() inliner (before) 25*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:v\d+>> InvokeStaticOrDirect 26*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ReturnVoid 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inlineEmptyMethod() inliner (after) 29*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect 30*795d594fSAndroid Build Coastguard Worker inlineEmptyMethod()31*795d594fSAndroid Build Coastguard Worker public static void inlineEmptyMethod() { 32*795d594fSAndroid Build Coastguard Worker OtherDex.emptyMethod(); 33*795d594fSAndroid Build Coastguard Worker } 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineReturnIntMethod() inliner (before) 36*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect 37*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineReturnIntMethod() inliner (after) 40*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineReturnIntMethod() inliner (after) 43*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Const38:i\d+>> IntConstant 38 44*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Const38>>] 45*795d594fSAndroid Build Coastguard Worker inlineReturnIntMethod()46*795d594fSAndroid Build Coastguard Worker public static int inlineReturnIntMethod() { 47*795d594fSAndroid Build Coastguard Worker return OtherDex.returnIntMethod(); 48*795d594fSAndroid Build Coastguard Worker } 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineOtherDexStatic() inliner (before) 51*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect method_name:OtherDex.returnOtherDexStatic 52*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 53*795d594fSAndroid Build Coastguard Worker 54*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineOtherDexStatic() inliner (after) 55*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect method_name:OtherDex.returnOtherDexStatic 56*795d594fSAndroid Build Coastguard Worker inlineOtherDexStatic()57*795d594fSAndroid Build Coastguard Worker public static int inlineOtherDexStatic() { 58*795d594fSAndroid Build Coastguard Worker return OtherDex.returnOtherDexStatic(); 59*795d594fSAndroid Build Coastguard Worker } 60*795d594fSAndroid Build Coastguard Worker 61*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineMainStatic() inliner (before) 62*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect 63*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineMainStatic() inliner (after) 66*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.inlineMainStatic() inliner (after) 69*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Static:i\d+>> StaticFieldGet 70*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Static>>] 71*795d594fSAndroid Build Coastguard Worker inlineMainStatic()72*795d594fSAndroid Build Coastguard Worker public static int inlineMainStatic() { 73*795d594fSAndroid Build Coastguard Worker return OtherDex.returnMainStatic(); 74*795d594fSAndroid Build Coastguard Worker } 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dontInlineRecursiveCall() inliner (before) 77*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect method_name:OtherDex.recursiveCall 78*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dontInlineRecursiveCall() inliner (after) 81*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect method_name:OtherDex.recursiveCall 82*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 83*795d594fSAndroid Build Coastguard Worker dontInlineRecursiveCall()84*795d594fSAndroid Build Coastguard Worker public static int dontInlineRecursiveCall() { 85*795d594fSAndroid Build Coastguard Worker return OtherDex.recursiveCall(); 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker 88*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.String Main.inlineReturnString() inliner (before) 89*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect method_name:OtherDex.returnString 90*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.String Main.inlineReturnString() inliner (after) 93*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect method_name:OtherDex.returnString 94*795d594fSAndroid Build Coastguard Worker inlineReturnString()95*795d594fSAndroid Build Coastguard Worker public static String inlineReturnString() { 96*795d594fSAndroid Build Coastguard Worker return OtherDex.returnString(); 97*795d594fSAndroid Build Coastguard Worker } 98*795d594fSAndroid Build Coastguard Worker 99*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexClass() inliner (before) 100*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect method_name:OtherDex.returnOtherDexClass 101*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexClass() inliner (after) 104*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect method_name:OtherDex.returnOtherDexClass 105*795d594fSAndroid Build Coastguard Worker inlineOtherDexClass()106*795d594fSAndroid Build Coastguard Worker public static Class<?> inlineOtherDexClass() { 107*795d594fSAndroid Build Coastguard Worker return OtherDex.returnOtherDexClass(); 108*795d594fSAndroid Build Coastguard Worker } 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (before) 111*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect 112*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after) 115*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after) 118*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Class:l\d+>>] 119*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Class>> LoadClass 120*795d594fSAndroid Build Coastguard Worker // Note: There are two LoadClass instructions. We obtain the correct 121*795d594fSAndroid Build Coastguard Worker // instruction id by matching the Return's input list first. 122*795d594fSAndroid Build Coastguard Worker inlineMainClass()123*795d594fSAndroid Build Coastguard Worker public static Class<?> inlineMainClass() { 124*795d594fSAndroid Build Coastguard Worker return OtherDex.returnMainClass(); 125*795d594fSAndroid Build Coastguard Worker } 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexClassStaticCall() inliner (before) 128*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect method_name:OtherDex.returnOtherDexClassStaticCall 129*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexClassStaticCall() inliner (after) 132*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect method_name:OtherDex.returnOtherDexClassStaticCall 133*795d594fSAndroid Build Coastguard Worker inlineOtherDexClassStaticCall()134*795d594fSAndroid Build Coastguard Worker public static Class<?> inlineOtherDexClassStaticCall() { 135*795d594fSAndroid Build Coastguard Worker return OtherDex.returnOtherDexClassStaticCall(); 136*795d594fSAndroid Build Coastguard Worker } 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (before) 139*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect 140*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Invoke>>] 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after) 143*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeStaticOrDirect 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after) 146*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Class:l\d+>>] 147*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Class>> LoadClass 148*795d594fSAndroid Build Coastguard Worker // Note: There are two LoadClass instructions. We obtain the correct 149*795d594fSAndroid Build Coastguard Worker // instruction id by matching the Return's input list first. 150*795d594fSAndroid Build Coastguard Worker inlineOtherDexCallingMain()151*795d594fSAndroid Build Coastguard Worker public static Class<?> inlineOtherDexCallingMain() { 152*795d594fSAndroid Build Coastguard Worker return OtherDex.returnOtherDexCallingMain(); 153*795d594fSAndroid Build Coastguard Worker } 154*795d594fSAndroid Build Coastguard Worker getOtherClass()155*795d594fSAndroid Build Coastguard Worker public static Class<?> getOtherClass() { 156*795d594fSAndroid Build Coastguard Worker return Main.class; 157*795d594fSAndroid Build Coastguard Worker } 158*795d594fSAndroid Build Coastguard Worker main(String[] args)159*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 160*795d594fSAndroid Build Coastguard Worker inlineEmptyMethod(); 161*795d594fSAndroid Build Coastguard Worker if (inlineReturnIntMethod() != 38) { 162*795d594fSAndroid Build Coastguard Worker throw new Error("Expected 38"); 163*795d594fSAndroid Build Coastguard Worker } 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker if (inlineOtherDexStatic() != 1) { 166*795d594fSAndroid Build Coastguard Worker throw new Error("Expected 1"); 167*795d594fSAndroid Build Coastguard Worker } 168*795d594fSAndroid Build Coastguard Worker 169*795d594fSAndroid Build Coastguard Worker if (inlineMainStatic() != 42) { 170*795d594fSAndroid Build Coastguard Worker throw new Error("Expected 42"); 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker 173*795d594fSAndroid Build Coastguard Worker if (inlineReturnString() != "OtherDex") { 174*795d594fSAndroid Build Coastguard Worker throw new Error("Expected OtherDex"); 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker if (inlineOtherDexClass() != OtherDex.class) { 178*795d594fSAndroid Build Coastguard Worker throw new Error("Expected " + OtherDex.class); 179*795d594fSAndroid Build Coastguard Worker } 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker if (inlineOtherDexClassStaticCall() != OtherDex.class) { 182*795d594fSAndroid Build Coastguard Worker throw new Error("Expected " + OtherDex.class); 183*795d594fSAndroid Build Coastguard Worker } 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker if (inlineMainClass() != Main.class) { 186*795d594fSAndroid Build Coastguard Worker throw new Error("Expected " + Main.class); 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker 189*795d594fSAndroid Build Coastguard Worker if (inlineOtherDexCallingMain() != Main.class) { 190*795d594fSAndroid Build Coastguard Worker throw new Error("Expected " + Main.class); 191*795d594fSAndroid Build Coastguard Worker } 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker // Reference the AAA class to ensure it is in the dex cache. 195*795d594fSAndroid Build Coastguard Worker public static Class<?> cls = AAA.class; 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker // Add a field that will be the first entry in the dex cache, to 198*795d594fSAndroid Build Coastguard Worker // avoid having the OtherDex.myStatic and Main.myStatic fields 199*795d594fSAndroid Build Coastguard Worker // share the same cache index. 200*795d594fSAndroid Build Coastguard Worker public static int aaa = 32; 201*795d594fSAndroid Build Coastguard Worker public static int myStatic = 42; 202*795d594fSAndroid Build Coastguard Worker } 203