< prev index next >

src/hotspot/cpu/x86/templateTable_x86.cpp

Print this page
rev 49172 : 8197405: Improve messages of AbstractMethodErrors and IncompatibleClassChangeErrors.
Reviewed-by: coleenp, dholmes, mdoerr, njian


3855   // Special case of invokeinterface called for virtual method of
3856   // java.lang.Object.  See cpCacheOop.cpp for details.
3857   // This code isn't produced by javac, but could be produced by
3858   // another compliant java compiler.
3859   Label notMethod;
3860   __ movl(rlocals, rdx);
3861   __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
3862 
3863   __ jcc(Assembler::zero, notMethod);
3864 
3865   invokevirtual_helper(rbx, rcx, rdx);
3866   __ bind(notMethod);
3867 
3868   // Get receiver klass into rdx - also a null check
3869   __ restore_locals();  // restore r14
3870   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
3871   __ load_klass(rdx, rcx);
3872 
3873   Label no_such_interface, no_such_method;
3874 


3875   // Receiver subtype check against REFC.
3876   // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
3877   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3878                              rdx, rax, noreg,
3879                              // outputs: scan temp. reg, scan temp. reg
3880                              rbcp, rlocals,
3881                              no_such_interface,
3882                              /*return_method=*/false);
3883 
3884   // profile this call
3885   __ restore_bcp(); // rbcp was destroyed by receiver type check
3886   __ profile_virtual_call(rdx, rbcp, rlocals);
3887 
3888   // Get declaring interface class from method, and itable index
3889   __ movptr(rax, Address(rbx, Method::const_offset()));
3890   __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
3891   __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
3892   __ movl(rbx, Address(rbx, Method::itable_index_offset()));
3893   __ subl(rbx, Method::itable_index_max);
3894   __ negl(rbx);
3895 


3896   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3897                              rdx, rax, rbx,
3898                              // outputs: method, scan temp. reg
3899                              rbx, rbcp,
3900                              no_such_interface);
3901 
3902   // rbx: Method* to call
3903   // rcx: receiver
3904   // Check for abstract method error
3905   // Note: This should be done more efficiently via a throw_abstract_method_error
3906   //       interpreter entry point and a conditional jump to it in case of a null
3907   //       method.
3908   __ testptr(rbx, rbx);
3909   __ jcc(Assembler::zero, no_such_method);
3910 
3911   __ profile_called_method(rbx, rbcp, rdx);
3912   __ profile_arguments_type(rdx, rbx, rbcp, true);
3913 
3914   // do the call
3915   // rcx: receiver
3916   // rbx,: Method*
3917   __ jump_from_interpreted(rbx, rdx);
3918   __ should_not_reach_here();
3919 
3920   // exception handling code follows...
3921   // note: must restore interpreter registers to canonical
3922   //       state for exception handling to work correctly!
3923 
3924   __ bind(no_such_method);
3925   // throw exception
3926   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
3927   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
3928   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3929   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3930   // the call_VM checks for exception, so we should never return here.











3931   __ should_not_reach_here();
3932 
3933   __ bind(no_such_interface);
3934   // throw exception
3935   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
3936   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
3937   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3938   __ call_VM(noreg, CAST_FROM_FN_PTR(address,
3939                    InterpreterRuntime::throw_IncompatibleClassChangeError));


3940   // the call_VM checks for exception, so we should never return here.
3941   __ should_not_reach_here();
3942 }
3943 
3944 void TemplateTable::invokehandle(int byte_no) {
3945   transition(vtos, vtos);
3946   assert(byte_no == f1_byte, "use this argument");
3947   const Register rbx_method = rbx;
3948   const Register rax_mtype  = rax;
3949   const Register rcx_recv   = rcx;
3950   const Register rdx_flags  = rdx;
3951 
3952   prepare_invoke(byte_no, rbx_method, rax_mtype, rcx_recv);
3953   __ verify_method_ptr(rbx_method);
3954   __ verify_oop(rcx_recv);
3955   __ null_check(rcx_recv);
3956 
3957   // rax: MethodType object (from cpool->resolved_references[f1], if necessary)
3958   // rbx: MH.invokeExact_MT method (from f2)
3959 




3855   // Special case of invokeinterface called for virtual method of
3856   // java.lang.Object.  See cpCacheOop.cpp for details.
3857   // This code isn't produced by javac, but could be produced by
3858   // another compliant java compiler.
3859   Label notMethod;
3860   __ movl(rlocals, rdx);
3861   __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
3862 
3863   __ jcc(Assembler::zero, notMethod);
3864 
3865   invokevirtual_helper(rbx, rcx, rdx);
3866   __ bind(notMethod);
3867 
3868   // Get receiver klass into rdx - also a null check
3869   __ restore_locals();  // restore r14
3870   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
3871   __ load_klass(rdx, rcx);
3872 
3873   Label no_such_interface, no_such_method;
3874 
3875   // Preserve method for throw_AbstractMethodErrorVerbose.
3876   __ mov(rcx, rbx);
3877   // Receiver subtype check against REFC.
3878   // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
3879   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3880                              rdx, rax, noreg,
3881                              // outputs: scan temp. reg, scan temp. reg
3882                              rbcp, rlocals,
3883                              no_such_interface,
3884                              /*return_method=*/false);
3885 
3886   // profile this call
3887   __ restore_bcp(); // rbcp was destroyed by receiver type check
3888   __ profile_virtual_call(rdx, rbcp, rlocals);
3889 
3890   // Get declaring interface class from method, and itable index
3891   __ movptr(rax, Address(rbx, Method::const_offset()));
3892   __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
3893   __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
3894   __ movl(rbx, Address(rbx, Method::itable_index_offset()));
3895   __ subl(rbx, Method::itable_index_max);
3896   __ negl(rbx);
3897 
3898   // Preserve recvKlass for throw_AbstractMethodErrorVerbose.
3899   __ mov(rlocals, rdx);
3900   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3901                              rlocals, rax, rbx,
3902                              // outputs: method, scan temp. reg
3903                              rbx, rbcp,
3904                              no_such_interface);
3905 
3906   // rbx: Method* to call
3907   // rcx: receiver
3908   // Check for abstract method error
3909   // Note: This should be done more efficiently via a throw_abstract_method_error
3910   //       interpreter entry point and a conditional jump to it in case of a null
3911   //       method.
3912   __ testptr(rbx, rbx);
3913   __ jcc(Assembler::zero, no_such_method);
3914 
3915   __ profile_called_method(rbx, rbcp, rdx);
3916   __ profile_arguments_type(rdx, rbx, rbcp, true);
3917 
3918   // do the call
3919   // rcx: receiver
3920   // rbx,: Method*
3921   __ jump_from_interpreted(rbx, rdx);
3922   __ should_not_reach_here();
3923 
3924   // exception handling code follows...
3925   // note: must restore interpreter registers to canonical
3926   //       state for exception handling to work correctly!
3927 
3928   __ bind(no_such_method);
3929   // throw exception
3930   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
3931   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
3932   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3933   // Pass arguments for generating a verbose error message.
3934 #ifdef _LP64
3935   Register recvKlass = c_rarg1;
3936   Register method    = c_rarg2;
3937   if (recvKlass != rdx) { __ movq(recvKlass, rdx); }
3938   if (method != rcx)    { __ movq(method, rcx);    }
3939 #else
3940   Register recvKlass = rdx;
3941   Register method    = rcx;
3942 #endif
3943   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
3944              recvKlass, method);
3945   // The call_VM checks for exception, so we should never return here.
3946   __ should_not_reach_here();
3947 
3948   __ bind(no_such_interface);
3949   // throw exception
3950   __ pop(rbx);           // pop return address (pushed by prepare_invoke)
3951   __ restore_bcp();      // rbcp must be correct for exception handler   (was destroyed)
3952   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3953   // Pass arguments for generating a verbose error message.
3954   LP64_ONLY( if (recvKlass != rdx) { __ movq(recvKlass, rdx); } )
3955   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
3956              recvKlass, rax);
3957   // the call_VM checks for exception, so we should never return here.
3958   __ should_not_reach_here();
3959 }
3960 
3961 void TemplateTable::invokehandle(int byte_no) {
3962   transition(vtos, vtos);
3963   assert(byte_no == f1_byte, "use this argument");
3964   const Register rbx_method = rbx;
3965   const Register rax_mtype  = rax;
3966   const Register rcx_recv   = rcx;
3967   const Register rdx_flags  = rdx;
3968 
3969   prepare_invoke(byte_no, rbx_method, rax_mtype, rcx_recv);
3970   __ verify_method_ptr(rbx_method);
3971   __ verify_oop(rcx_recv);
3972   __ null_check(rcx_recv);
3973 
3974   // rax: MethodType object (from cpool->resolved_references[f1], if necessary)
3975   // rbx: MH.invokeExact_MT method (from f2)
3976 


< prev index next >