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;