< prev index next >

src/hotspot/cpu/x86/templateTable_x86.cpp

Print this page

        

@@ -3789,19 +3789,33 @@
   // rax: reference klass (from f1)
   // rbx: method (from f2)
   // rcx: receiver
   // rdx: flags
 
+  Label no_such_interface; // for receiver subtype check
+  Register recvKlass; // used for exception processing
+
   // Check for private method invocation - indicated by vfinal
   Label notVFinal;
   __ movl(rlocals, rdx);
   __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
   __ jcc(Assembler::zero, notVFinal);
 
-  // do the call - rbx is actually the method to call
+  // Get receiver klass into rlocals - also a null check
+  __ null_check(rcx, oopDesc::klass_offset_in_bytes());
+  __ load_klass(rlocals, rcx);
 
-  __ null_check(rcx);
+  Label subtype;
+  __ check_klass_subtype(rlocals, rax, rbcp, subtype);
+  // If we get here the typecheck failed
+  recvKlass = rdx;
+  __ mov(recvKlass, rlocals); // shuffle receiver class for exception use
+  __ jmp(no_such_interface);
+
+  __ bind(subtype);
+
+  // do the call - rbx is actually the method to call
 
   __ profile_final_call(rdx);
   __ profile_arguments_type(rdx, rbx, rbcp, true);
 
   __ jump_from_interpreted(rbx, rdx);

@@ -3824,11 +3838,11 @@
   // Get receiver klass into rdx - also a null check
   __ restore_locals();  // restore r14
   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   __ load_klass(rdx, rcx);
 
-  Label no_such_interface, no_such_method;
+  Label no_such_method;
 
   // Preserve method for throw_AbstractMethodErrorVerbose.
   __ mov(rcx, rbx);
   // Receiver subtype check against REFC.
   // Superklass in rax. Subklass in rdx. Blows rcx, rdi.

@@ -3886,16 +3900,16 @@
   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
   // Pass arguments for generating a verbose error message.
 #ifdef _LP64
-  Register recvKlass = c_rarg1;
+  recvKlass = c_rarg1;
   Register method    = c_rarg2;
   if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
   if (method != rcx)    { __ movq(method, rcx);    }
 #else
-  Register recvKlass = rdx;
+  recvKlass = rdx;
   Register method    = rcx;
 #endif
   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
              recvKlass, method);
   // The call_VM checks for exception, so we should never return here.
< prev index next >