src/cpu/x86/vm/templateTable_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File valhalla Sdiff src/cpu/x86/vm

src/cpu/x86/vm/templateTable_x86.cpp

Print this page




3599   ShouldNotReachHere();
3600 }
3601 
3602 void TemplateTable::prepare_invoke(int byte_no,
3603                                    Register method,  // linked method (or i-klass)
3604                                    Register index,   // itable index, MethodType, etc.
3605                                    Register recv,    // if caller wants to see it
3606                                    Register flags    // if caller wants to test it
3607                                    ) {
3608   // determine flags
3609   const Bytecodes::Code code = bytecode();
3610   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
3611   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
3612   const bool is_invokehandle     = code == Bytecodes::_invokehandle;
3613   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
3614   const bool is_invokedirect     = code == Bytecodes::_invokedirect;
3615   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
3616   const bool load_receiver       = (recv  != noreg);
3617   const bool save_flags          = (flags != noreg);
3618   assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
3619   assert(save_flags    == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
3620   assert(flags == noreg || flags == rdx, "");
3621   assert(recv  == noreg || recv  == rcx, "");
3622 
3623   // setup registers & access constant pool cache
3624   if (recv  == noreg)  recv  = rcx;
3625   if (flags == noreg)  flags = rdx;
3626   assert_different_registers(method, index, recv, flags);
3627 
3628   // save 'interpreter return address'
3629   __ save_bcp();
3630 
3631   load_invoke_cp_cache_entry(byte_no, method, index, flags,
3632                              is_invokevirtual || is_invokedirect,
3633                              false, is_invokedynamic);
3634 
3635   // maybe push appendix to arguments (just before return address)
3636   if (is_invokedynamic || is_invokehandle) {
3637     Label L_no_push;
3638     __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift));
3639     __ jcc(Assembler::zero, L_no_push);


3734   __ profile_arguments_type(rdx, method, rbcp, true);
3735   __ jump_from_interpreted(method, rdx);
3736 }
3737 
3738 void TemplateTable::invokevirtual(int byte_no) {
3739   transition(vtos, vtos);
3740   assert(byte_no == f2_byte, "use this argument");
3741   prepare_invoke(byte_no,
3742                  rbx,    // method or vtable index
3743                  noreg,  // unused itable index
3744                  rcx, rdx); // recv, flags
3745 
3746   // rbx: index
3747   // rcx: receiver
3748   // rdx: flags
3749 
3750   invokevirtual_helper(rbx, rcx, rdx);
3751 }
3752 
3753 /*
3754  * Dummy implemented basically as invokevirtual (blindly uses resolve_invokevirtual),
3755  * but assumes it picks out a final call (unsure about interfaces, default
3756  * methods and where "Value.equals(QValue;)Z" should live at this point in time)

3757  */
3758 void TemplateTable::invokedirect(int byte_no) {
3759   transition(vtos, vtos);
3760   assert(byte_no == f2_byte, "use this argument");
3761   prepare_invoke(byte_no, rbx, noreg, rcx); // recv, flags









3762 
3763   __ verify_oop(rcx);
3764   __ null_check(rcx);
3765 
3766   __ profile_final_call(rax);
3767   __ profile_arguments_type(rax, rbx, rbcp, true);
3768   __ jump_from_interpreted(rbx, rax);



3769 }
3770 
3771 void TemplateTable::invokespecial(int byte_no) {
3772   transition(vtos, vtos);
3773   assert(byte_no == f1_byte, "use this argument");
3774   prepare_invoke(byte_no, rbx, noreg,  // get f1 Method*
3775                  rcx);  // get receiver also for null check
3776   __ verify_oop(rcx);
3777   __ null_check(rcx);
3778   // do the call
3779   __ profile_call(rax);
3780   __ profile_arguments_type(rax, rbx, rbcp, false);
3781   __ jump_from_interpreted(rbx, rax);
3782 }
3783 
3784 void TemplateTable::invokestatic(int byte_no) {
3785   transition(vtos, vtos);
3786   assert(byte_no == f1_byte, "use this argument");
3787   prepare_invoke(byte_no, rbx);  // get f1 Method*
3788   // do the call




3599   ShouldNotReachHere();
3600 }
3601 
3602 void TemplateTable::prepare_invoke(int byte_no,
3603                                    Register method,  // linked method (or i-klass)
3604                                    Register index,   // itable index, MethodType, etc.
3605                                    Register recv,    // if caller wants to see it
3606                                    Register flags    // if caller wants to test it
3607                                    ) {
3608   // determine flags
3609   const Bytecodes::Code code = bytecode();
3610   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
3611   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
3612   const bool is_invokehandle     = code == Bytecodes::_invokehandle;
3613   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
3614   const bool is_invokedirect     = code == Bytecodes::_invokedirect;
3615   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
3616   const bool load_receiver       = (recv  != noreg);
3617   const bool save_flags          = (flags != noreg);
3618   assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
3619   assert(save_flags    == (is_invokeinterface || is_invokevirtual || is_invokedirect), "need flags for vfinal");
3620   assert(flags == noreg || flags == rdx, "");
3621   assert(recv  == noreg || recv  == rcx, "");
3622 
3623   // setup registers & access constant pool cache
3624   if (recv  == noreg)  recv  = rcx;
3625   if (flags == noreg)  flags = rdx;
3626   assert_different_registers(method, index, recv, flags);
3627 
3628   // save 'interpreter return address'
3629   __ save_bcp();
3630 
3631   load_invoke_cp_cache_entry(byte_no, method, index, flags,
3632                              is_invokevirtual || is_invokedirect,
3633                              false, is_invokedynamic);
3634 
3635   // maybe push appendix to arguments (just before return address)
3636   if (is_invokedynamic || is_invokehandle) {
3637     Label L_no_push;
3638     __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift));
3639     __ jcc(Assembler::zero, L_no_push);


3734   __ profile_arguments_type(rdx, method, rbcp, true);
3735   __ jump_from_interpreted(method, rdx);
3736 }
3737 
3738 void TemplateTable::invokevirtual(int byte_no) {
3739   transition(vtos, vtos);
3740   assert(byte_no == f2_byte, "use this argument");
3741   prepare_invoke(byte_no,
3742                  rbx,    // method or vtable index
3743                  noreg,  // unused itable index
3744                  rcx, rdx); // recv, flags
3745 
3746   // rbx: index
3747   // rcx: receiver
3748   // rdx: flags
3749 
3750   invokevirtual_helper(rbx, rcx, rdx);
3751 }
3752 
3753 /*
3754  * The invokedirect bytecode is implemented as an invokevirtual bytecode:
3755  * The implementation blindly uses resolve_invokevirtual() and assumes
3756  * that a final call will be picked at the end. (Currently unsure about interfaces,
3757  * default methods, and about where "Value.equals(QValue;)Z" should live.)
3758  */
3759 void TemplateTable::invokedirect(int byte_no) {
3760   transition(vtos, vtos);
3761   assert(byte_no == f2_byte, "use this argument");
3762   prepare_invoke(byte_no,
3763                  rbx,       // method (and not vtable index, as the method to be invoked should be final)
3764                  noreg,
3765                  rcx, rdx); // recv, flags
3766 
3767   // Check if the method is final
3768   Label notFinal;
3769   __ movl(rax, rdx);
3770   __ andl(rax, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
3771   __ jcc(Assembler::zero, notFinal);
3772 
3773   __ verify_oop(rcx);
3774   __ null_check(rcx);

3775   __ profile_final_call(rax);
3776   __ profile_arguments_type(rax, rbx, rbcp, true);
3777   __ jump_from_interpreted(rbx, rax);
3778 
3779   __ bind(notFinal);
3780   __ stop("Interpreter observed a non-final method as a target of an invokedirect instruction");
3781 }
3782 
3783 void TemplateTable::invokespecial(int byte_no) {
3784   transition(vtos, vtos);
3785   assert(byte_no == f1_byte, "use this argument");
3786   prepare_invoke(byte_no, rbx, noreg,  // get f1 Method*
3787                  rcx);  // get receiver also for null check
3788   __ verify_oop(rcx);
3789   __ null_check(rcx);
3790   // do the call
3791   __ profile_call(rax);
3792   __ profile_arguments_type(rax, rbx, rbcp, false);
3793   __ jump_from_interpreted(rbx, rax);
3794 }
3795 
3796 void TemplateTable::invokestatic(int byte_no) {
3797   transition(vtos, vtos);
3798   assert(byte_no == f1_byte, "use this argument");
3799   prepare_invoke(byte_no, rbx);  // get f1 Method*
3800   // do the call


src/cpu/x86/vm/templateTable_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File