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 )) |
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; |