< prev index next >
src/hotspot/cpu/x86/templateTable_x86.cpp
Print this page
rev 50604 : imported patch jep181-rev1
*** 3790,3823 ****
transition(vtos, vtos);
assert(byte_no == f1_byte, "use this argument");
prepare_invoke(byte_no, rax, rbx, // get f1 Klass*, f2 Method*
rcx, rdx); // recv, flags
! // rax: reference klass (from f1)
// rbx: method (from f2)
// rcx: receiver
// rdx: flags
// 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;
__ movl(rlocals, rdx);
__ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
! __ jcc(Assembler::zero, notMethod);
! invokevirtual_helper(rbx, rcx, rdx);
! __ bind(notMethod);
// 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.
--- 3790,3854 ----
transition(vtos, vtos);
assert(byte_no == f1_byte, "use this argument");
prepare_invoke(byte_no, rax, rbx, // get f1 Klass*, f2 Method*
rcx, rdx); // recv, flags
! // rax: reference klass (from f1) if interface method
// rbx: method (from f2)
// rcx: receiver
// rdx: flags
+ // First check for Object case, then private interface method,
+ // then regular interface method.
+
// Special case of invokeinterface called for virtual method of
! // java.lang.Object. See cpCache.cpp for details.
! Label notObjectMethod;
__ movl(rlocals, rdx);
__ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
+ __ jcc(Assembler::zero, notObjectMethod);
+ invokevirtual_helper(rbx, rcx, rdx);
+ // no return from above
+ __ bind(notObjectMethod);
! 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);
! // no return from above
! __ bind(notVFinal);
// 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.
*** 3875,3890 ****
__ 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.
--- 3906,3921 ----
__ 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 >