< 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 >