src/hotspot/cpu/ppc/templateTable_ppc_64.cpp
changeset 50735 2f2af62dfac7
parent 50728 9375184cec98
child 50814 f3b70d115fb3
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Fri Jun 22 17:49:21 2018 -0700
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Sat Jun 23 01:32:41 2018 -0400
@@ -3583,14 +3583,46 @@
 
   prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1);
 
-  // Get receiver klass.
+  // First check for Object case, then private interface method,
+  // then regular interface method.
+
+  // 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 corner case object method.
-  Label LobjectMethod, L_no_such_interface, Lthrow_ame;
+  // Special case of invokeinterface called for virtual method of
+  // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
+  // The invokeinterface was rewritten to a invokevirtual, hence we have
+  // to handle this corner case.
+
+  Label LnotObjectMethod, Lthrow_ame;
   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
-  __ btrue(CCR0, LobjectMethod);
+  __ bfalse(CCR0, LnotObjectMethod);
+  invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
+  __ bind(LnotObjectMethod);
+
+  // Check for private method invocation - indicated by vfinal
+  Label LnotVFinal, L_no_such_interface, L_subtype;
+
+  __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
+  __ bfalse(CCR0, LnotVFinal);
+
+  __ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch1, Rscratch2, L_subtype);
+  // If we get here the typecheck failed
+  __ b(L_no_such_interface);
+  __ bind(L_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);
 
   __ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
                              L_no_such_interface, /*return_method=*/false);
@@ -3631,14 +3663,6 @@
   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
           Rrecv_klass, Rinterface_klass);
   DEBUG_ONLY( __ should_not_reach_here(); )
-
-  // Special case of invokeinterface called for virtual method of
-  // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
-  // The invokeinterface was rewritten to a invokevirtual, hence we have
-  // to handle this corner case. This code isn't produced by javac, but could
-  // be produced by another compliant java compiler.
-  __ bind(LobjectMethod);
-  invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
 }
 
 void TemplateTable::invokedynamic(int byte_no) {