1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2017 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 public class MostDerived extends Derived { test(Class main)18*795d594fSAndroid Build Coastguard Worker public static void test(Class main) { 19*795d594fSAndroid Build Coastguard Worker // The defining class loader of MostDerived (MDCL) is also the initiating loader of 20*795d594fSAndroid Build Coastguard Worker // superclass Derived but delegates the loading to its parent class loader (PCL) which 21*795d594fSAndroid Build Coastguard Worker // defines both Derived and Base. Thus Derived.class is recorded in MDCL's ClassTable 22*795d594fSAndroid Build Coastguard Worker // but the Base.class is not because the Base's initiating loader is PCL. This is the 23*795d594fSAndroid Build Coastguard Worker // case when loading the MostDerived class and remains the case after resolving the 24*795d594fSAndroid Build Coastguard Worker // "invoke-super Derived.foo(.)" called from from MostDerived.foo(.). When that 25*795d594fSAndroid Build Coastguard Worker // invoke-super is executed from AOT-compiled code, it goes through the .bss ArtMethod* 26*795d594fSAndroid Build Coastguard Worker // entry and on first execution goes through the resolution method. After resolving to 27*795d594fSAndroid Build Coastguard Worker // the Base.foo(.), the artQuickResolutionTrampoline() used to erroneously fill the 28*795d594fSAndroid Build Coastguard Worker // Base.foo(.) entry in the MostDerived's DexCache which is wrong as the referenced 29*795d594fSAndroid Build Coastguard Worker // class Base is not in the associated, i.e. MDCL's, ClassTable. 30*795d594fSAndroid Build Coastguard Worker new MostDerived().foo(main); 31*795d594fSAndroid Build Coastguard Worker try { 32*795d594fSAndroid Build Coastguard Worker // This discrepancy then used to crash when resolving the Base.foo(.) method 33*795d594fSAndroid Build Coastguard Worker // for JIT compilation of another method. 34*795d594fSAndroid Build Coastguard Worker main.getDeclaredMethod("ensureJitCompiled", Class.class, String.class).invoke( 35*795d594fSAndroid Build Coastguard Worker null, MostDerived.class, "bar"); 36*795d594fSAndroid Build Coastguard Worker } catch (Throwable t) { 37*795d594fSAndroid Build Coastguard Worker t.printStackTrace(System.out); 38*795d594fSAndroid Build Coastguard Worker } 39*795d594fSAndroid Build Coastguard Worker System.out.println("MostDerived.test(.) done."); 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker foo(Class main)42*795d594fSAndroid Build Coastguard Worker public void foo(Class main) { 43*795d594fSAndroid Build Coastguard Worker super.foo(main); 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker bar(Class main)46*795d594fSAndroid Build Coastguard Worker public void bar(Class main) { 47*795d594fSAndroid Build Coastguard Worker Base b = this; 48*795d594fSAndroid Build Coastguard Worker b.foo(main); 49*795d594fSAndroid Build Coastguard Worker } 50*795d594fSAndroid Build Coastguard Worker } 51