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 |