658 // The registers have been saved in the standard places. Perform
659 // an exception lookup in the caller and dispatch to the handler
660 // if found. Otherwise unwind and dispatch to the callers
661 // exception handler.
662 oop_map = generate_oop_map(sasm, 1 /*thread*/);
663
664 // load and clear pending exception oop into RAX
665 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
666 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
667
668 // load issuing PC (the return address for this stub) into rdx
669 __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
670
671 // make sure that the vm_results are cleared (may be unnecessary)
672 __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
673 __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
674 break;
675 case handle_exception_nofpu_id:
676 case handle_exception_id:
677 // At this point all registers MAY be live.
678 oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id);
679 break;
680 case handle_exception_from_callee_id: {
681 // At this point all registers except exception oop (RAX) and
682 // exception pc (RDX) are dead.
683 const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord);
684 oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0);
685 sasm->set_frame_size(frame_size);
686 WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes));
687 break;
688 }
689 default: ShouldNotReachHere();
690 }
691
692 #ifdef TIERED
693 // C2 can leave the fpu stack dirty
694 if (UseSSE < 2) {
695 __ empty_FPU_stack();
696 }
697 #endif // TIERED
698
731 // compute the exception handler.
732 // the exception oop and the throwing pc are read from the fields in JavaThread
733 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
734 oop_maps->add_gc_map(call_offset, oop_map);
735
736 // rax: handler address
737 // will be the deopt blob if nmethod was deoptimized while we looked up
738 // handler regardless of whether handler existed in the nmethod.
739
740 // only rax, is valid at this time, all other registers have been destroyed by the runtime call
741 __ invalidate_registers(false, true, true, true, true, true);
742
743 // patch the return address, this stub will directly return to the exception handler
744 __ movptr(Address(rbp, 1*BytesPerWord), rax);
745
746 switch (id) {
747 case forward_exception_id:
748 case handle_exception_nofpu_id:
749 case handle_exception_id:
750 // Restore the registers that were saved at the beginning.
751 restore_live_registers(sasm, id == handle_exception_nofpu_id);
752 break;
753 case handle_exception_from_callee_id:
754 // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP
755 // since we do a leave anyway.
756
757 // Pop the return address since we are possibly changing SP (restoring from BP).
758 __ leave();
759 __ pop(rcx);
760
761 // Restore SP from BP if the exception PC is a method handle call site.
762 NOT_LP64(__ get_thread(thread);)
763 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
764 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save);
765 __ jmp(rcx); // jump to exception handler
766 break;
767 default: ShouldNotReachHere();
768 }
769
770 return oop_maps;
771 }
|
658 // The registers have been saved in the standard places. Perform
659 // an exception lookup in the caller and dispatch to the handler
660 // if found. Otherwise unwind and dispatch to the callers
661 // exception handler.
662 oop_map = generate_oop_map(sasm, 1 /*thread*/);
663
664 // load and clear pending exception oop into RAX
665 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
666 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
667
668 // load issuing PC (the return address for this stub) into rdx
669 __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
670
671 // make sure that the vm_results are cleared (may be unnecessary)
672 __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
673 __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
674 break;
675 case handle_exception_nofpu_id:
676 case handle_exception_id:
677 // At this point all registers MAY be live.
678 oop_map = save_live_registers(sasm, 1 /*thread*/, id != handle_exception_nofpu_id);
679 break;
680 case handle_exception_from_callee_id: {
681 // At this point all registers except exception oop (RAX) and
682 // exception pc (RDX) are dead.
683 const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord);
684 oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0);
685 sasm->set_frame_size(frame_size);
686 WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes));
687 break;
688 }
689 default: ShouldNotReachHere();
690 }
691
692 #ifdef TIERED
693 // C2 can leave the fpu stack dirty
694 if (UseSSE < 2) {
695 __ empty_FPU_stack();
696 }
697 #endif // TIERED
698
731 // compute the exception handler.
732 // the exception oop and the throwing pc are read from the fields in JavaThread
733 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
734 oop_maps->add_gc_map(call_offset, oop_map);
735
736 // rax: handler address
737 // will be the deopt blob if nmethod was deoptimized while we looked up
738 // handler regardless of whether handler existed in the nmethod.
739
740 // only rax, is valid at this time, all other registers have been destroyed by the runtime call
741 __ invalidate_registers(false, true, true, true, true, true);
742
743 // patch the return address, this stub will directly return to the exception handler
744 __ movptr(Address(rbp, 1*BytesPerWord), rax);
745
746 switch (id) {
747 case forward_exception_id:
748 case handle_exception_nofpu_id:
749 case handle_exception_id:
750 // Restore the registers that were saved at the beginning.
751 restore_live_registers(sasm, id != handle_exception_nofpu_id);
752 break;
753 case handle_exception_from_callee_id:
754 // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP
755 // since we do a leave anyway.
756
757 // Pop the return address since we are possibly changing SP (restoring from BP).
758 __ leave();
759 __ pop(rcx);
760
761 // Restore SP from BP if the exception PC is a method handle call site.
762 NOT_LP64(__ get_thread(thread);)
763 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
764 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save);
765 __ jmp(rcx); // jump to exception handler
766 break;
767 default: ShouldNotReachHere();
768 }
769
770 return oop_maps;
771 }
|