comparison src/cpu/x86/vm/templateTable_x86_32.cpp @ 1059:389049f3f393

6858164: invokedynamic code needs some cleanup (post-6655638) Summary: Fix several crashers, remove needless paths for boxed-style bootstrap method call, refactor & simplify APIs for rewriter constantPoolOop, remove sun.dyn.CallSiteImpl Reviewed-by: kvn
author jrose
date Fri, 30 Oct 2009 16:22:59 -0700
parents be93aad57795
children 85f13cdfbc1d
comparison
equal deleted inserted replaced
1058:73a726751507 1059:389049f3f393
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