Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 3371:fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
Reviewed-by: jrose, kvn, never
author | twisti |
---|---|
date | Thu, 12 May 2011 14:04:48 -0700 |
parents | 167b70ff3abc |
children | a80577f854f9 |
comparison
equal
deleted
inserted
replaced
3370:2f17eb233d13 | 3371:fabcf26ee72f |
---|---|
161 | 161 |
162 (*bounce_offset) = __ pc() - start; | 162 (*bounce_offset) = __ pc() - start; |
163 BLOCK_COMMENT("ricochet_blob.bounce"); | 163 BLOCK_COMMENT("ricochet_blob.bounce"); |
164 | 164 |
165 if (VerifyMethodHandles) RicochetFrame::verify_clean(_masm); | 165 if (VerifyMethodHandles) RicochetFrame::verify_clean(_masm); |
166 trace_method_handle(_masm, "ricochet_blob.bounce"); | 166 trace_method_handle(_masm, "return/ricochet_blob.bounce"); |
167 | 167 |
168 __ jmp(frame_address(continuation_offset_in_bytes())); | 168 __ jmp(frame_address(continuation_offset_in_bytes())); |
169 __ hlt(); | 169 __ hlt(); |
170 DEBUG_ONLY(__ push(MAGIC_NUMBER_2)); | 170 DEBUG_ONLY(__ push(MAGIC_NUMBER_2)); |
171 | 171 |
613 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1)); | 613 __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1)); |
614 insert_arg_slots(_masm, 2 * stack_move_unit(), | 614 insert_arg_slots(_masm, 2 * stack_move_unit(), |
615 rcx_argslot, rbx_temp, rdx_temp); | 615 rcx_argslot, rbx_temp, rdx_temp); |
616 | 616 |
617 // load up an adapter from the calling type (Java weaves this) | 617 // load up an adapter from the calling type (Java weaves this) |
618 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp))); | |
619 Register rdx_adapter = rdx_temp; | 618 Register rdx_adapter = rdx_temp; |
620 // __ load_heap_oop(rdx_adapter, Address(rdx_temp, java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes())); | 619 __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp))); |
621 // deal with old JDK versions: | 620 __ load_heap_oop(rdx_adapter, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp))); |
622 __ lea(rdi_temp, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp))); | 621 __ verify_oop(rdx_adapter); |
623 __ cmpptr(rdi_temp, rdx_temp); | |
624 Label sorry_no_invoke_generic; | |
625 __ jcc(Assembler::below, sorry_no_invoke_generic); | |
626 | |
627 __ load_heap_oop(rdx_adapter, Address(rdi_temp, 0)); | |
628 __ testptr(rdx_adapter, rdx_adapter); | |
629 __ jcc(Assembler::zero, sorry_no_invoke_generic); | |
630 __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter); | 622 __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter); |
631 // As a trusted first argument, pass the type being called, so the adapter knows | 623 // As a trusted first argument, pass the type being called, so the adapter knows |
632 // the actual types of the arguments and return values. | 624 // the actual types of the arguments and return values. |
633 // (Generic invokers are shared among form-families of method-type.) | 625 // (Generic invokers are shared among form-families of method-type.) |
634 __ movptr(Address(rcx_argslot, 0 * Interpreter::stackElementSize), rax_mtype); | 626 __ movptr(Address(rcx_argslot, 0 * Interpreter::stackElementSize), rax_mtype); |
635 // FIXME: assert that rdx_adapter is of the right method-type. | 627 // FIXME: assert that rdx_adapter is of the right method-type. |
636 __ mov(rcx, rdx_adapter); | 628 __ mov(rcx, rdx_adapter); |
637 trace_method_handle(_masm, "invokeGeneric"); | 629 trace_method_handle(_masm, "invokeGeneric"); |
638 __ jump_to_method_handle_entry(rcx, rdi_temp); | 630 __ jump_to_method_handle_entry(rcx, rdi_temp); |
639 | |
640 __ bind(sorry_no_invoke_generic); // no invokeGeneric implementation available! | |
641 __ movptr(rcx_recv, Address(rcx_argslot, -1 * Interpreter::stackElementSize)); // recover original MH | |
642 __ push(rax_mtype); // required mtype | |
643 __ push(rcx_recv); // bad mh (1st stacked argument) | |
644 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); | |
645 | 631 |
646 return entry_point; | 632 return entry_point; |
647 } | 633 } |
648 | 634 |
649 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant. | 635 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant. |
686 // pull one word down each time through the loop | 672 // pull one word down each time through the loop |
687 __ movptr(rbx_temp, Address(rdx_temp, 0)); | 673 __ movptr(rbx_temp, Address(rdx_temp, 0)); |
688 __ movptr(Address(rdx_temp, arg_slots, Interpreter::stackElementScale()), rbx_temp); | 674 __ movptr(Address(rdx_temp, arg_slots, Interpreter::stackElementScale()), rbx_temp); |
689 __ addptr(rdx_temp, wordSize); | 675 __ addptr(rdx_temp, wordSize); |
690 __ cmpptr(rdx_temp, rax_argslot); | 676 __ cmpptr(rdx_temp, rax_argslot); |
691 __ jcc(Assembler::less, loop); | 677 __ jcc(Assembler::below, loop); |
692 } | 678 } |
693 | 679 |
694 // Now move the argslot down, to point to the opened-up space. | 680 // Now move the argslot down, to point to the opened-up space. |
695 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Interpreter::stackElementScale())); | 681 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Interpreter::stackElementScale())); |
696 BLOCK_COMMENT("} insert_arg_slots"); | 682 BLOCK_COMMENT("} insert_arg_slots"); |
729 // pull one word up each time through the loop | 715 // pull one word up each time through the loop |
730 __ movptr(rbx_temp, Address(rdx_temp, 0)); | 716 __ movptr(rbx_temp, Address(rdx_temp, 0)); |
731 __ movptr(Address(rdx_temp, arg_slots, Interpreter::stackElementScale()), rbx_temp); | 717 __ movptr(Address(rdx_temp, arg_slots, Interpreter::stackElementScale()), rbx_temp); |
732 __ addptr(rdx_temp, -wordSize); | 718 __ addptr(rdx_temp, -wordSize); |
733 __ cmpptr(rdx_temp, rsp); | 719 __ cmpptr(rdx_temp, rsp); |
734 __ jcc(Assembler::greaterEqual, loop); | 720 __ jcc(Assembler::aboveEqual, loop); |
735 } | 721 } |
736 | 722 |
737 // Now move the argslot up, to point to the just-copied block. | 723 // Now move the argslot up, to point to the just-copied block. |
738 __ lea(rsp, Address(rsp, arg_slots, Interpreter::stackElementScale())); | 724 __ lea(rsp, Address(rsp, arg_slots, Interpreter::stackElementScale())); |
739 // And adjust the argslot address to point at the deletion point. | 725 // And adjust the argslot address to point at the deletion point. |
978 intptr_t* saved_regs, | 964 intptr_t* saved_regs, |
979 intptr_t* entry_sp, | 965 intptr_t* entry_sp, |
980 intptr_t* saved_sp, | 966 intptr_t* saved_sp, |
981 intptr_t* saved_bp) { | 967 intptr_t* saved_bp) { |
982 // called as a leaf from native code: do not block the JVM! | 968 // called as a leaf from native code: do not block the JVM! |
969 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have rcx_mh | |
983 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; | 970 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; |
984 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; | 971 intptr_t* base_sp = last_sp; |
985 tty->print_cr("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT, | 972 typedef MethodHandles::RicochetFrame RicochetFrame; |
986 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); | 973 RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes()); |
987 if (last_sp != saved_sp && last_sp != NULL) | 974 if (!UseRicochetFrames || Universe::heap()->is_in((address) rfp->saved_args_base())) { |
988 tty->print_cr("*** last_sp="INTPTR_FORMAT, (intptr_t)last_sp); | 975 // Probably an interpreter frame. |
976 base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; | |
977 } | |
978 intptr_t mh_reg = (intptr_t)mh; | |
979 const char* mh_reg_name = "rcx_mh"; | |
980 if (!has_mh) mh_reg_name = "rcx"; | |
981 tty->print_cr("MH %s %s="PTR_FORMAT" sp=("PTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="PTR_FORMAT, | |
982 adaptername, mh_reg_name, mh_reg, | |
983 (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); | |
989 if (Verbose) { | 984 if (Verbose) { |
990 tty->print(" reg dump: "); | 985 tty->print(" reg dump: "); |
991 int saved_regs_count = (entry_sp-1) - saved_regs; | 986 int saved_regs_count = (entry_sp-1) - saved_regs; |
992 // 32 bit: rdi rsi rbp rsp; rbx rdx rcx (*) rax | 987 // 32 bit: rdi rsi rbp rsp; rbx rdx rcx (*) rax |
993 int i; | 988 int i; |
994 for (i = 0; i <= saved_regs_count; i++) { | 989 for (i = 0; i <= saved_regs_count; i++) { |
995 if (i > 0 && i % 4 == 0 && i != saved_regs_count) { | 990 if (i > 0 && i % 4 == 0 && i != saved_regs_count) { |
996 tty->cr(); | 991 tty->cr(); |
997 tty->print(" + dump: "); | 992 tty->print(" + dump: "); |
998 } | 993 } |
999 tty->print(" %d: "INTPTR_FORMAT, i, saved_regs[i]); | 994 tty->print(" %d: "PTR_FORMAT, i, saved_regs[i]); |
1000 } | 995 } |
1001 tty->cr(); | 996 tty->cr(); |
997 if (last_sp != saved_sp && last_sp != NULL) | |
998 tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp); | |
1002 int stack_dump_count = 16; | 999 int stack_dump_count = 16; |
1003 if (stack_dump_count < (int)(saved_bp + 2 - saved_sp)) | 1000 if (stack_dump_count < (int)(saved_bp + 2 - saved_sp)) |
1004 stack_dump_count = (int)(saved_bp + 2 - saved_sp); | 1001 stack_dump_count = (int)(saved_bp + 2 - saved_sp); |
1005 if (stack_dump_count > 64) stack_dump_count = 48; | 1002 if (stack_dump_count > 64) stack_dump_count = 48; |
1006 for (i = 0; i < stack_dump_count; i += 4) { | 1003 for (i = 0; i < stack_dump_count; i += 4) { |
1007 tty->print_cr(" dump at SP[%d] "INTPTR_FORMAT": "INTPTR_FORMAT" "INTPTR_FORMAT" "INTPTR_FORMAT" "INTPTR_FORMAT, | 1004 tty->print_cr(" dump at SP[%d] "PTR_FORMAT": "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT, |
1008 i, (intptr_t) &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]); | 1005 i, (intptr_t) &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]); |
1009 } | 1006 } |
1010 print_method_handle(mh); | 1007 if (has_mh) |
1008 print_method_handle(mh); | |
1011 } | 1009 } |
1012 } | 1010 } |
1013 | 1011 |
1014 // The stub wraps the arguments in a struct on the stack to avoid | 1012 // The stub wraps the arguments in a struct on the stack to avoid |
1015 // dealing with the different calling conventions for passing 6 | 1013 // dealing with the different calling conventions for passing 6 |
1071 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS) | 1069 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS) |
1072 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS) | 1070 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS) |
1073 //OP_COLLECT_ARGS is below... | 1071 //OP_COLLECT_ARGS is below... |
1074 |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) | 1072 |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) |
1075 |(!UseRicochetFrames ? 0 : | 1073 |(!UseRicochetFrames ? 0 : |
1076 LP64_ONLY(FLAG_IS_DEFAULT(UseRicochetFrames) ? 0 :) | |
1077 java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 : | 1074 java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 : |
1078 ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF) | 1075 ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF) |
1079 |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS) | 1076 |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS) |
1080 |(1<<java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS) | 1077 |(1<<java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS) |
1081 )) | 1078 )) |
1544 __ movflt(vmarg, xmm0); | 1541 __ movflt(vmarg, xmm0); |
1545 } | 1542 } |
1546 #else //_LP64 | 1543 #else //_LP64 |
1547 if (ek == _adapter_opt_f2d) { | 1544 if (ek == _adapter_opt_f2d) { |
1548 __ fld_s(vmarg); // load float to ST0 | 1545 __ fld_s(vmarg); // load float to ST0 |
1549 __ fstp_s(vmarg); // store single | 1546 __ fstp_d(vmarg); // store double |
1550 } else { | 1547 } else { |
1551 __ fld_d(vmarg); // load double to ST0 | 1548 __ fld_d(vmarg); // load double to ST0 |
1552 __ fstp_s(vmarg); // store single | 1549 __ fstp_s(vmarg); // store single |
1553 } | 1550 } |
1554 #endif //_LP64 | 1551 #endif //_LP64 |
2351 move_typed_arg(_masm, elem_type, true, | 2348 move_typed_arg(_masm, elem_type, true, |
2352 Address(rdx_fill_ptr, 0), Address(rsi_source, 0), | 2349 Address(rdx_fill_ptr, 0), Address(rsi_source, 0), |
2353 rbx_temp, rdi_temp); | 2350 rbx_temp, rdi_temp); |
2354 __ addptr(rsi_source, type2aelembytes(elem_type)); | 2351 __ addptr(rsi_source, type2aelembytes(elem_type)); |
2355 __ cmpptr(rdx_fill_ptr, rax_argslot); | 2352 __ cmpptr(rdx_fill_ptr, rax_argslot); |
2356 __ jcc(Assembler::greater, loop); | 2353 __ jcc(Assembler::above, loop); |
2357 } else if (length_constant == 0) { | 2354 } else if (length_constant == 0) { |
2358 // nothing to copy | 2355 // nothing to copy |
2359 } else { | 2356 } else { |
2360 int elem_offset = elem0_offset; | 2357 int elem_offset = elem0_offset; |
2361 int slot_offset = length_constant * Interpreter::stackElementSize; | 2358 int slot_offset = length_constant * Interpreter::stackElementSize; |