636 // save code can segv when fxsave instructions find improperly |
636 // save code can segv when fxsave instructions find improperly |
637 // aligned stack pointer. |
637 // aligned stack pointer. |
638 |
638 |
639 __ movptr(rax, Address(rsp, 0)); |
639 __ movptr(rax, Address(rsp, 0)); |
640 |
640 |
|
641 // Must preserve original SP for loading incoming arguments because |
|
642 // we need to align the outgoing SP for compiled code. |
|
643 __ movptr(r11, rsp); |
|
644 |
641 // Cut-out for having no stack args. Since up to 2 int/oop args are passed |
645 // Cut-out for having no stack args. Since up to 2 int/oop args are passed |
642 // in registers, we will occasionally have no stack args. |
646 // in registers, we will occasionally have no stack args. |
643 int comp_words_on_stack = 0; |
647 int comp_words_on_stack = 0; |
644 if (comp_args_on_stack) { |
648 if (comp_args_on_stack) { |
645 // Sig words on the stack are greater-than VMRegImpl::stack0. Those in |
649 // Sig words on the stack are greater-than VMRegImpl::stack0. Those in |
658 __ andptr(rsp, -16); |
662 __ andptr(rsp, -16); |
659 |
663 |
660 // push the return address and misalign the stack that youngest frame always sees |
664 // push the return address and misalign the stack that youngest frame always sees |
661 // as far as the placement of the call instruction |
665 // as far as the placement of the call instruction |
662 __ push(rax); |
666 __ push(rax); |
|
667 |
|
668 // Put saved SP in another register |
|
669 const Register saved_sp = rax; |
|
670 __ movptr(saved_sp, r11); |
663 |
671 |
664 // Will jump to the compiled code just as if compiled code was doing it. |
672 // Will jump to the compiled code just as if compiled code was doing it. |
665 // Pre-load the register-jump target early, to schedule it better. |
673 // Pre-load the register-jump target early, to schedule it better. |
666 __ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); |
674 __ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); |
667 |
675 |
678 // Pick up 0, 1 or 2 words from SP+offset. |
686 // Pick up 0, 1 or 2 words from SP+offset. |
679 |
687 |
680 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), |
688 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), |
681 "scrambled load targets?"); |
689 "scrambled load targets?"); |
682 // Load in argument order going down. |
690 // Load in argument order going down. |
683 // int ld_off = (total_args_passed + comp_words_on_stack -i)*wordSize; |
691 int ld_off = (total_args_passed - i)*Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); |
684 // base ld_off on r13 (sender_sp) as the stack alignment makes offsets from rsp |
|
685 // unpredictable |
|
686 int ld_off = ((total_args_passed - 1) - i)*Interpreter::stackElementSize(); |
|
687 |
|
688 // Point to interpreter value (vs. tag) |
692 // Point to interpreter value (vs. tag) |
689 int next_off = ld_off - Interpreter::stackElementSize(); |
693 int next_off = ld_off - Interpreter::stackElementSize(); |
690 // |
694 // |
691 // |
695 // |
692 // |
696 // |
697 continue; |
701 continue; |
698 } |
702 } |
699 if (r_1->is_stack()) { |
703 if (r_1->is_stack()) { |
700 // Convert stack slot to an SP offset (+ wordSize to account for return address ) |
704 // Convert stack slot to an SP offset (+ wordSize to account for return address ) |
701 int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size + wordSize; |
705 int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size + wordSize; |
|
706 |
|
707 // We can use r13 as a temp here because compiled code doesn't need r13 as an input |
|
708 // and if we end up going thru a c2i because of a miss a reasonable value of r13 |
|
709 // will be generated. |
702 if (!r_2->is_valid()) { |
710 if (!r_2->is_valid()) { |
703 // sign extend??? |
711 // sign extend??? |
704 __ movl(rax, Address(r13, ld_off)); |
712 __ movl(r13, Address(saved_sp, ld_off)); |
705 __ movptr(Address(rsp, st_off), rax); |
713 __ movptr(Address(rsp, st_off), r13); |
706 } else { |
714 } else { |
707 // |
715 // |
708 // We are using two optoregs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE |
716 // We are using two optoregs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE |
709 // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case |
717 // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case |
710 // So we must adjust where to pick up the data to match the interpreter. |
718 // So we must adjust where to pick up the data to match the interpreter. |
713 // are accessed as negative so LSW is at LOW address |
721 // are accessed as negative so LSW is at LOW address |
714 |
722 |
715 // ld_off is MSW so get LSW |
723 // ld_off is MSW so get LSW |
716 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? |
724 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? |
717 next_off : ld_off; |
725 next_off : ld_off; |
718 __ movq(rax, Address(r13, offset)); |
726 __ movq(r13, Address(saved_sp, offset)); |
719 // st_off is LSW (i.e. reg.first()) |
727 // st_off is LSW (i.e. reg.first()) |
720 __ movq(Address(rsp, st_off), rax); |
728 __ movq(Address(rsp, st_off), r13); |
721 } |
729 } |
722 } else if (r_1->is_Register()) { // Register argument |
730 } else if (r_1->is_Register()) { // Register argument |
723 Register r = r_1->as_Register(); |
731 Register r = r_1->as_Register(); |
724 assert(r != rax, "must be different"); |
732 assert(r != rax, "must be different"); |
725 if (r_2->is_valid()) { |
733 if (r_2->is_valid()) { |
730 |
738 |
731 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? |
739 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? |
732 next_off : ld_off; |
740 next_off : ld_off; |
733 |
741 |
734 // this can be a misaligned move |
742 // this can be a misaligned move |
735 __ movq(r, Address(r13, offset)); |
743 __ movq(r, Address(saved_sp, offset)); |
736 } else { |
744 } else { |
737 // sign extend and use a full word? |
745 // sign extend and use a full word? |
738 __ movl(r, Address(r13, ld_off)); |
746 __ movl(r, Address(saved_sp, ld_off)); |
739 } |
747 } |
740 } else { |
748 } else { |
741 if (!r_2->is_valid()) { |
749 if (!r_2->is_valid()) { |
742 __ movflt(r_1->as_XMMRegister(), Address(r13, ld_off)); |
750 __ movflt(r_1->as_XMMRegister(), Address(saved_sp, ld_off)); |
743 } else { |
751 } else { |
744 __ movdbl(r_1->as_XMMRegister(), Address(r13, next_off)); |
752 __ movdbl(r_1->as_XMMRegister(), Address(saved_sp, next_off)); |
745 } |
753 } |
746 } |
754 } |
747 } |
755 } |
748 |
756 |
749 // 6243940 We might end up in handle_wrong_method if |
757 // 6243940 We might end up in handle_wrong_method if |
3317 __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog |
3325 __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog |
3318 __ pop(rdx); // No need for exception pc anymore |
3326 __ pop(rdx); // No need for exception pc anymore |
3319 |
3327 |
3320 // rax: exception handler |
3328 // rax: exception handler |
3321 |
3329 |
|
3330 // Restore SP from BP if the exception PC is a MethodHandle call. |
|
3331 __ cmpl(Address(r15_thread, JavaThread::is_method_handle_exception_offset()), 0); |
|
3332 __ cmovptr(Assembler::notEqual, rsp, rbp); |
|
3333 |
3322 // We have a handler in rax (could be deopt blob). |
3334 // We have a handler in rax (could be deopt blob). |
3323 __ mov(r8, rax); |
3335 __ mov(r8, rax); |
3324 |
3336 |
3325 // Get the exception oop |
3337 // Get the exception oop |
3326 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); |
3338 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); |