--- old/src/hotspot/cpu/sparc/templateTable_sparc.cpp 2018-05-04 00:46:48.211137840 -0400 +++ new/src/hotspot/cpu/sparc/templateTable_sparc.cpp 2018-05-04 00:46:46.667048287 -0400 @@ -3056,16 +3056,29 @@ prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags); + Label L_no_such_interface; + // Check for private method invocation - indicated by vfinal Label notVFinal; - __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), Rscratch); - __ btst(O1_flags, Rscratch); - __ br(Assembler::zero, false, Assembler::pt, notVFinal); - __ delayed()->nop(); - - __ null_check(O0_recv); - { + __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), Rscratch); + __ btst(O1_flags, Rscratch); + __ br(Assembler::zero, false, Assembler::pt, notVFinal); + __ delayed()->nop(); + + // get receiver klass - this is also a null check + __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); + __ load_klass(O0_recv, O2_Klass); + + Label subtype; + Register Rtemp = O1_flags; + __ check_klass_subtype(O2_Klass, Rinterface, Rscratch, Rtemp, subtype); + // If we get here the typecheck failed + __ ba(L_no_such_interface); + __ delayed()->nop(); + __ bind(subtype); + + // do the call Register Rcall = Rinterface; __ mov(Rmethod, G5_method); assert_different_registers(Rcall, G5_method, Gargs, Rret); @@ -3074,9 +3087,9 @@ __ profile_final_call(Rscratch); __ call_from_interpreter(Rcall, Gargs, Rret); } - __ bind(notVFinal); + __ bind(notVFinal); - // get receiver klass + // get receiver klass - this is also a null check __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); __ load_klass(O0_recv, O2_Klass); @@ -3096,8 +3109,6 @@ Register Rtemp = O1_flags; - Label L_no_such_interface; - // Receiver subtype check against REFC. __ lookup_interface_method(// inputs: rec. class, interface, itable index O2_Klass, Rinterface, noreg,