Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/graalRuntime_x86.cpp @ 9471:5fa54bf57f8c
replaced exception_handler_nofpu assembler stub with a compiled stub (GRAAL-81)
generalized stub printf mechanism to also serve as a fatal VM exit message
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 01 May 2013 17:46:12 +0200 |
parents | 902a974d55c8 |
children | 99ef9bcb3f32 |
comparison
equal
deleted
inserted
replaced
9466:b8cae7920bca | 9471:5fa54bf57f8c |
---|---|
610 __ pop(rcx); | 610 __ pop(rcx); |
611 __ addptr(rsp, BytesPerWord); | 611 __ addptr(rsp, BytesPerWord); |
612 #endif // _LP64 | 612 #endif // _LP64 |
613 } | 613 } |
614 | 614 |
615 OopMapSet* GraalRuntime::generate_handle_exception(StubID id, GraalStubAssembler *sasm) { | |
616 __ block_comment("generate_handle_exception"); | |
617 | |
618 // incoming parameters | |
619 const Register exception_oop = rax; | |
620 const Register exception_pc = rdx; | |
621 // other registers used in this stub | |
622 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); | |
623 | |
624 // Save registers, if required. | |
625 OopMapSet* oop_maps = new OopMapSet(); | |
626 OopMap* oop_map = NULL; | |
627 switch (id) { | |
628 case handle_exception_nofpu_id: | |
629 // At this point all registers MAY be live. | |
630 oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id); | |
631 break; | |
632 default: ShouldNotReachHere(); | |
633 } | |
634 | |
635 #ifdef TIERED | |
636 // C2 can leave the fpu stack dirty | |
637 if (UseSSE < 2) { | |
638 __ empty_FPU_stack(); | |
639 } | |
640 #endif // TIERED | |
641 | |
642 // verify that only rax, and rdx is valid at this time | |
643 #ifdef ASSERT | |
644 __ movptr(rbx, 0xDEAD); | |
645 __ movptr(rcx, 0xDEAD); | |
646 __ movptr(rsi, 0xDEAD); | |
647 __ movptr(rdi, 0xDEAD); | |
648 #endif | |
649 | |
650 // verify that rax, contains a valid exception | |
651 __ verify_not_null_oop(exception_oop); | |
652 | |
653 // load address of JavaThread object for thread-local data | |
654 NOT_LP64(__ get_thread(thread);) | |
655 | |
656 #ifdef ASSERT | |
657 // check that fields in JavaThread for exception oop and issuing pc are | |
658 // empty before writing to them | |
659 Label oop_empty; | |
660 __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); | |
661 __ jcc(Assembler::equal, oop_empty); | |
662 __ stop("exception oop already set"); | |
663 __ bind(oop_empty); | |
664 | |
665 Label pc_empty; | |
666 __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); | |
667 __ jcc(Assembler::equal, pc_empty); | |
668 __ stop("exception pc already set"); | |
669 __ bind(pc_empty); | |
670 #endif | |
671 | |
672 // save exception oop and issuing pc into JavaThread | |
673 // (exception handler will load it from here) | |
674 __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); | |
675 __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); | |
676 | |
677 // patch throwing pc into return address (has bci & oop map) | |
678 __ movptr(Address(rbp, 1*BytesPerWord), exception_pc); | |
679 | |
680 // compute the exception handler. | |
681 // the exception oop and the throwing pc are read from the fields in JavaThread | |
682 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); | |
683 oop_maps->add_gc_map(call_offset, oop_map); | |
684 | |
685 // rax: handler address | |
686 // will be the deopt blob if nmethod was deoptimized while we looked up | |
687 // handler regardless of whether handler existed in the nmethod. | |
688 | |
689 // only rax, is valid at this time, all other registers have been destroyed by the runtime call | |
690 #ifdef ASSERT | |
691 __ movptr(rbx, 0xDEAD); | |
692 __ movptr(rcx, 0xDEAD); | |
693 __ movptr(rdx, 0xDEAD); | |
694 __ movptr(rsi, 0xDEAD); | |
695 __ movptr(rdi, 0xDEAD); | |
696 #endif | |
697 | |
698 // patch the return address, this stub will directly return to the exception handler | |
699 __ movptr(Address(rbp, 1*BytesPerWord), rax); | |
700 | |
701 switch (id) { | |
702 case handle_exception_nofpu_id: | |
703 // Restore the registers that were saved at the beginning. | |
704 restore_live_registers(sasm, id == handle_exception_nofpu_id); | |
705 break; | |
706 default: ShouldNotReachHere(); | |
707 } | |
708 | |
709 return oop_maps; | |
710 } | |
711 | |
712 void GraalRuntime::generate_unwind_exception(GraalStubAssembler *sasm) { | 615 void GraalRuntime::generate_unwind_exception(GraalStubAssembler *sasm) { |
713 // incoming parameters | 616 // incoming parameters |
714 const Register exception_oop = rax; | 617 const Register exception_oop = rax; |
715 // callee-saved copy of exception_oop during runtime call | 618 // callee-saved copy of exception_oop during runtime call |
716 const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14); | 619 const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14); |
808 bool save_fpu_registers = true; | 711 bool save_fpu_registers = true; |
809 | 712 |
810 // stub code & info for the different stubs | 713 // stub code & info for the different stubs |
811 OopMapSet* oop_maps = NULL; | 714 OopMapSet* oop_maps = NULL; |
812 switch (id) { | 715 switch (id) { |
813 | |
814 case handle_exception_nofpu_id: | |
815 { GraalStubFrame f(sasm, "handle_exception", dont_gc_arguments); | |
816 oop_maps = generate_handle_exception(id, sasm); | |
817 } | |
818 break; | |
819 | 716 |
820 case unwind_exception_call_id: { | 717 case unwind_exception_call_id: { |
821 // remove the frame from the stack | 718 // remove the frame from the stack |
822 __ movptr(rsp, rbp); | 719 __ movptr(rsp, rbp); |
823 __ pop(rbp); | 720 __ pop(rbp); |