src/cpu/x86/vm/sharedRuntime_x86_64.cpp

changeset 1570
e66fd840cb6b
parent 1283
fe95187e8882
child 1622
cf0685d550f1
equal deleted inserted replaced
1569:0910903272e5 1570:e66fd840cb6b
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()));

mercurial