< prev index next >

src/hotspot/cpu/arm/templateTable_arm.cpp

Print this page

        

@@ -4277,24 +4277,39 @@
   const Register Rflags  = R3_tmp;
   const Register Rklass  = R3_tmp;
 
   prepare_invoke(byte_no, Rinterf, Rmethod, Rrecv, Rflags);
 
-  // Special case of invokeinterface called for virtual method of
-  // java.lang.Object.  See cpCacheOop.cpp for details.
-  // This code isn't produced by javac, but could be produced by
-  // another compliant java compiler.
-  Label notMethod;
-  __ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
-
-  invokevirtual_helper(Rmethod, Rrecv, Rflags);
-  __ bind(notMethod);
+  // First check for Object case, then private interface method,
+  // then regular interface method.
 
   // Get receiver klass into Rklass - also a null check
   __ load_klass(Rklass, Rrecv);
 
+  // Special case of invokeinterface called for virtual method of
+  // java.lang.Object.  See cpCache.cpp for details.
+  Label notObjectMethod;
+  __ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod);
+  invokevirtual_helper(Rmethod, Rrecv, Rflags);
+  __ bind(notObjectMethod);
+
+  // Check for private method invocation - indicated by vfinal
   Label no_such_interface;
+  Label notVFinal;
+  __ tbz(Rflags, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal);
+
+  Label subtype;
+  __ check_klass_subtype(Rklass, Rinterf, R1_tmp, R0_tmp, subtype);
+  // If we get here the typecheck failed
+  __ b(no_such_interface);
+  __ bind(subtype);
+
+  // do the call - the index is actually the method to call
+  __ profile_final_call(R0_tmp);
+  __ jump_from_interpreted(Rindex);
+
+  __ bind(notVFinal);
 
   // Receiver subtype check against REFC.
   __ lookup_interface_method(// inputs: rec. class, interface
                              Rklass, Rinterf, noreg,
                              // outputs:  scan temp. reg1, scan temp. reg2
< prev index next >