hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
changeset 4429 d7eb4e2099aa
parent 2570 ecc7862946d4
child 4478 c3a8af0fc6b0
equal deleted inserted replaced
4428:d1617f46285d 4429:d7eb4e2099aa
  2888   ShouldNotReachHere();
  2888   ShouldNotReachHere();
  2889 }
  2889 }
  2890 
  2890 
  2891 
  2891 
  2892 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
  2892 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
  2893   bool is_invdyn_bootstrap = (byte_no < 0);
       
  2894   if (is_invdyn_bootstrap)  byte_no = -byte_no;
       
  2895 
       
  2896   // determine flags
  2893   // determine flags
  2897   Bytecodes::Code code = bytecode();
  2894   Bytecodes::Code code = bytecode();
  2898   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
  2895   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
  2899   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
  2896   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
  2900   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
  2897   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
  2905   // setup registers & access constant pool cache
  2902   // setup registers & access constant pool cache
  2906   const Register recv   = rcx;
  2903   const Register recv   = rcx;
  2907   const Register flags  = rdx;
  2904   const Register flags  = rdx;
  2908   assert_different_registers(method, index, recv, flags);
  2905   assert_different_registers(method, index, recv, flags);
  2909 
  2906 
  2910   assert(!is_invdyn_bootstrap || is_invokedynamic, "byte_no<0 hack only for invdyn");
       
  2911 
       
  2912   // save 'interpreter return address'
  2907   // save 'interpreter return address'
  2913   __ save_bcp();
  2908   __ save_bcp();
  2914 
  2909 
  2915   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual);
  2910   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual);
  2916 
  2911 
  2942   // Make sure we don't need to mask flags for tosBits after the above shift
  2937   // Make sure we don't need to mask flags for tosBits after the above shift
  2943   ConstantPoolCacheEntry::verify_tosBits();
  2938   ConstantPoolCacheEntry::verify_tosBits();
  2944   // load return address
  2939   // load return address
  2945   {
  2940   {
  2946     address table_addr;
  2941     address table_addr;
  2947     if (is_invdyn_bootstrap)
  2942     if (is_invokeinterface || is_invokedynamic)
  2948       table_addr = (address)Interpreter::return_5_unbox_addrs_by_index_table();
       
  2949     else if (is_invokeinterface || is_invokedynamic)
       
  2950       table_addr = (address)Interpreter::return_5_addrs_by_index_table();
  2943       table_addr = (address)Interpreter::return_5_addrs_by_index_table();
  2951     else
  2944     else
  2952       table_addr = (address)Interpreter::return_3_addrs_by_index_table();
  2945       table_addr = (address)Interpreter::return_3_addrs_by_index_table();
  2953     ExternalAddress table(table_addr);
  2946     ExternalAddress table(table_addr);
  2954     __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
  2947     __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
  3152     // profile this call
  3145     // profile this call
  3153     __ profile_call(rsi);
  3146     __ profile_call(rsi);
  3154   }
  3147   }
  3155 
  3148 
  3156   Label handle_unlinked_site;
  3149   Label handle_unlinked_site;
  3157   __ movptr(rcx, Address(rax, __ delayed_value(sun_dyn_CallSiteImpl::target_offset_in_bytes, rcx)));
  3150   __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
  3158   __ testptr(rcx, rcx);
  3151   __ null_check(rcx);
  3159   __ jcc(Assembler::zero, handle_unlinked_site);
       
  3160 
       
  3161   __ prepare_to_jump_from_interpreted();
  3152   __ prepare_to_jump_from_interpreted();
  3162   __ jump_to_method_handle_entry(rcx, rdx);
       
  3163 
       
  3164   // Initial calls come here...
       
  3165   __ bind(handle_unlinked_site);
       
  3166   __ pop(rcx);                 // remove return address pushed by prepare_invoke
       
  3167 
       
  3168   // box stacked arguments into an array for the bootstrap method
       
  3169   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);
       
  3170   __ restore_bcp();      // rsi must be correct for call_VM
       
  3171   __ call_VM(rax, entry, rax);
       
  3172   __ movl(rdi, rax);            // protect bootstrap MH from prepare_invoke
       
  3173 
       
  3174   // recompute return address
       
  3175   __ restore_bcp();      // rsi must be correct for prepare_invoke
       
  3176   prepare_invoke(rax, rbx, -byte_no);  // smashes rcx, rdx
       
  3177   // rax: CallSite object (f1)
       
  3178   // rbx: unused (f2)
       
  3179   // rdi: bootstrap MH
       
  3180   // rdx: flags
       
  3181 
       
  3182   // now load up the arglist, which has been neatly boxed
       
  3183   __ get_thread(rcx);
       
  3184   __ movptr(rdx, Address(rcx, JavaThread::vm_result_2_offset()));
       
  3185   __ movptr(Address(rcx, JavaThread::vm_result_2_offset()), NULL_WORD);
       
  3186   __ verify_oop(rdx);
       
  3187   // rdx = arglist
       
  3188 
       
  3189   // save SP now, before we add the bootstrap call to the stack
       
  3190   // We must preserve a fiction that the original arguments are outgoing,
       
  3191   // because the return sequence will reset the stack to this point
       
  3192   // and then pop all those arguments.  It seems error-prone to use
       
  3193   // a different argument list size just for bootstrapping.
       
  3194   __ prepare_to_jump_from_interpreted();
       
  3195 
       
  3196   // Now let's play adapter, pushing the real arguments on the stack.
       
  3197   __ pop(rbx);                  // return PC
       
  3198   __ push(rdi);                 // boot MH
       
  3199   __ push(rax);                 // call site
       
  3200   __ push(rdx);                 // arglist
       
  3201   __ push(rbx);                 // return PC, again
       
  3202   __ mov(rcx, rdi);
       
  3203   __ jump_to_method_handle_entry(rcx, rdx);
  3153   __ jump_to_method_handle_entry(rcx, rdx);
  3204 }
  3154 }
  3205 
  3155 
  3206 //----------------------------------------------------------------------------------------------------
  3156 //----------------------------------------------------------------------------------------------------
  3207 // Allocation
  3157 // Allocation