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