src/hotspot/cpu/x86/templateTable_x86.cpp
changeset 50735 2f2af62dfac7
parent 50728 9375184cec98
child 51056 3ddf41505d54
equal deleted inserted replaced
50734:0828a0f6676b 50735:2f2af62dfac7
  3790   transition(vtos, vtos);
  3790   transition(vtos, vtos);
  3791   assert(byte_no == f1_byte, "use this argument");
  3791   assert(byte_no == f1_byte, "use this argument");
  3792   prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 Method*
  3792   prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 Method*
  3793                  rcx, rdx); // recv, flags
  3793                  rcx, rdx); // recv, flags
  3794 
  3794 
  3795   // rax: reference klass (from f1)
  3795   // rax: reference klass (from f1) if interface method
  3796   // rbx: method (from f2)
  3796   // rbx: method (from f2)
  3797   // rcx: receiver
  3797   // rcx: receiver
  3798   // rdx: flags
  3798   // rdx: flags
  3799 
  3799 
       
  3800   // First check for Object case, then private interface method,
       
  3801   // then regular interface method.
       
  3802 
  3800   // Special case of invokeinterface called for virtual method of
  3803   // Special case of invokeinterface called for virtual method of
  3801   // java.lang.Object.  See cpCacheOop.cpp for details.
  3804   // java.lang.Object.  See cpCache.cpp for details.
  3802   // This code isn't produced by javac, but could be produced by
  3805   Label notObjectMethod;
  3803   // another compliant java compiler.
       
  3804   Label notMethod;
       
  3805   __ movl(rlocals, rdx);
  3806   __ movl(rlocals, rdx);
  3806   __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
  3807   __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
  3807 
  3808   __ jcc(Assembler::zero, notObjectMethod);
  3808   __ jcc(Assembler::zero, notMethod);
       
  3809 
       
  3810   invokevirtual_helper(rbx, rcx, rdx);
  3809   invokevirtual_helper(rbx, rcx, rdx);
  3811   __ bind(notMethod);
  3810   // no return from above
       
  3811   __ bind(notObjectMethod);
       
  3812 
       
  3813   Label no_such_interface; // for receiver subtype check
       
  3814   Register recvKlass; // used for exception processing
       
  3815 
       
  3816   // Check for private method invocation - indicated by vfinal
       
  3817   Label notVFinal;
       
  3818   __ movl(rlocals, rdx);
       
  3819   __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
       
  3820   __ jcc(Assembler::zero, notVFinal);
       
  3821 
       
  3822   // Get receiver klass into rlocals - also a null check
       
  3823   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
       
  3824   __ load_klass(rlocals, rcx);
       
  3825 
       
  3826   Label subtype;
       
  3827   __ check_klass_subtype(rlocals, rax, rbcp, subtype);
       
  3828   // If we get here the typecheck failed
       
  3829   recvKlass = rdx;
       
  3830   __ mov(recvKlass, rlocals); // shuffle receiver class for exception use
       
  3831   __ jmp(no_such_interface);
       
  3832 
       
  3833   __ bind(subtype);
       
  3834 
       
  3835   // do the call - rbx is actually the method to call
       
  3836 
       
  3837   __ profile_final_call(rdx);
       
  3838   __ profile_arguments_type(rdx, rbx, rbcp, true);
       
  3839 
       
  3840   __ jump_from_interpreted(rbx, rdx);
       
  3841   // no return from above
       
  3842   __ bind(notVFinal);
  3812 
  3843 
  3813   // Get receiver klass into rdx - also a null check
  3844   // Get receiver klass into rdx - also a null check
  3814   __ restore_locals();  // restore r14
  3845   __ restore_locals();  // restore r14
  3815   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
  3846   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
  3816   __ load_klass(rdx, rcx);
  3847   __ load_klass(rdx, rcx);
  3817 
  3848 
  3818   Label no_such_interface, no_such_method;
  3849   Label no_such_method;
  3819 
  3850 
  3820   // Preserve method for throw_AbstractMethodErrorVerbose.
  3851   // Preserve method for throw_AbstractMethodErrorVerbose.
  3821   __ mov(rcx, rbx);
  3852   __ mov(rcx, rbx);
  3822   // Receiver subtype check against REFC.
  3853   // Receiver subtype check against REFC.
  3823   // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
  3854   // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
  3875   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
  3906   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
  3876   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
  3907   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
  3877   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
  3908   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
  3878   // Pass arguments for generating a verbose error message.
  3909   // Pass arguments for generating a verbose error message.
  3879 #ifdef _LP64
  3910 #ifdef _LP64
  3880   Register recvKlass = c_rarg1;
  3911   recvKlass = c_rarg1;
  3881   Register method    = c_rarg2;
  3912   Register method    = c_rarg2;
  3882   if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
  3913   if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
  3883   if (method != rcx)    { __ movq(method, rcx);    }
  3914   if (method != rcx)    { __ movq(method, rcx);    }
  3884 #else
  3915 #else
  3885   Register recvKlass = rdx;
  3916   recvKlass = rdx;
  3886   Register method    = rcx;
  3917   Register method    = rcx;
  3887 #endif
  3918 #endif
  3888   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
  3919   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
  3889              recvKlass, method);
  3920              recvKlass, method);
  3890   // The call_VM checks for exception, so we should never return here.
  3921   // The call_VM checks for exception, so we should never return here.