< prev index next >

src/hotspot/cpu/ppc/templateTable_ppc_64.cpp

Print this page

        

@@ -3583,33 +3583,38 @@
                  Rrecv_klass      = R4_ARG2,
                  Rflags           = R7_ARG5;
 
   prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1);
 
+  // Get receiver klass - this is also a null check
+  __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
+  __ load_klass(Rrecv_klass, Rreceiver);
+
   // Check for private method invocation - indicated by vfinal
-  Label LnotVFinal;
+  Label LnotVFinal, L_no_such_interface, L_subtype;
 
   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
   __ bfalse(CCR0, LnotVFinal);
 
-  __ null_check_throw(Rreceiver, -1, Rscratch3);
+  __ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch, Rscratch1, subtype);
+  // If we get here the typecheck failed
+  __ b(L_no_such_interface);
+  __ bind(subtype);
+
+  // do the call
 
   Register Rscratch = Rflags; // Rflags is dead now.
 
   __ profile_final_call(Rscratch1, Rscratch);
   __ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true);
 
   __ call_from_interpreter(Rindex, Rret_addr, Rscratch, Rrecv_klass /* scratch */);
 
   __ bind(LnotVFinal);
 
-  // Get receiver klass.
-  __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
-  __ load_klass(Rrecv_klass, Rreceiver);
-
   // Check corner case object method.
-  Label LobjectMethod, L_no_such_interface, Lthrow_ame;
+  Label LobjectMethod, Lthrow_ame;
   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
   __ btrue(CCR0, LobjectMethod);
 
   __ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
                              L_no_such_interface, /*return_method=*/false);
< prev index next >