< prev index next >
src/hotspot/cpu/x86/templateTable_x86.cpp
Print this page
*** 3789,3807 ****
// rax: reference klass (from f1)
// rbx: method (from f2)
// rcx: receiver
// rdx: flags
// 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
! __ null_check(rcx);
__ profile_final_call(rdx);
__ profile_arguments_type(rdx, rbx, rbcp, true);
__ jump_from_interpreted(rbx, rdx);
--- 3789,3821 ----
// 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);
! // Get receiver klass into rlocals - also a null check
! __ null_check(rcx, oopDesc::klass_offset_in_bytes());
! __ load_klass(rlocals, 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,3834 ****
// 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;
// Preserve method for throw_AbstractMethodErrorVerbose.
__ mov(rcx, rbx);
// Receiver subtype check against REFC.
// Superklass in rax. Subklass in rdx. Blows rcx, rdi.
--- 3838,3848 ----
// 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_method;
// Preserve method for throw_AbstractMethodErrorVerbose.
__ mov(rcx, rbx);
// Receiver subtype check against REFC.
// Superklass in rax. Subklass in rdx. Blows rcx, rdi.
*** 3886,3901 ****
__ 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;
Register method = c_rarg2;
if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
if (method != rcx) { __ movq(method, rcx); }
#else
! Register 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.
--- 3900,3915 ----
__ 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
! recvKlass = c_rarg1;
Register method = c_rarg2;
if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
if (method != rcx) { __ movq(method, rcx); }
#else
! 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 >