comparison src/cpu/x86/vm/c1_Runtime1_x86.cpp @ 1295:3cf667df43ef

6919934: JSR 292 needs to support x86 C1 Summary: This implements JSR 292 support for C1 x86. Reviewed-by: never, jrose, kvn
author twisti
date Tue, 09 Mar 2010 20:16:19 +0100
parents bd441136a5ce
children 93767e6a2dfd
comparison
equal deleted inserted replaced
1293:51db1e4b379d 1295:3cf667df43ef
1 /* 1 /*
2 * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
686 // compute the exception handler. 686 // compute the exception handler.
687 // the exception oop and the throwing pc are read from the fields in JavaThread 687 // the exception oop and the throwing pc are read from the fields in JavaThread
688 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); 688 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
689 oop_maps->add_gc_map(call_offset, oop_map); 689 oop_maps->add_gc_map(call_offset, oop_map);
690 690
691 // rax,: handler address or NULL if no handler exists 691 // rax,: handler address
692 // will be the deopt blob if nmethod was deoptimized while we looked up 692 // will be the deopt blob if nmethod was deoptimized while we looked up
693 // handler regardless of whether handler existed in the nmethod. 693 // handler regardless of whether handler existed in the nmethod.
694 694
695 // only rax, is valid at this time, all other registers have been destroyed by the runtime call 695 // only rax, is valid at this time, all other registers have been destroyed by the runtime call
696 __ invalidate_registers(false, true, true, true, true, true); 696 __ invalidate_registers(false, true, true, true, true, true);
697 697
698 #ifdef ASSERT
698 // Do we have an exception handler in the nmethod? 699 // Do we have an exception handler in the nmethod?
699 Label no_handler;
700 Label done; 700 Label done;
701 __ testptr(rax, rax); 701 __ testptr(rax, rax);
702 __ jcc(Assembler::zero, no_handler); 702 __ jcc(Assembler::notZero, done);
703 __ stop("no handler found");
704 __ bind(done);
705 #endif
703 706
704 // exception handler found 707 // exception handler found
705 // patch the return address -> the stub will directly return to the exception handler 708 // patch the return address -> the stub will directly return to the exception handler
706 __ movptr(Address(rbp, 1*BytesPerWord), rax); 709 __ movptr(Address(rbp, 1*BytesPerWord), rax);
707 710
710 713
711 // return to exception handler 714 // return to exception handler
712 __ leave(); 715 __ leave();
713 __ ret(0); 716 __ ret(0);
714 717
715 __ bind(no_handler);
716 // no exception handler found in this method, so the exception is
717 // forwarded to the caller (using the unwind code of the nmethod)
718 // there is no need to restore the registers
719
720 // restore the real return address that was saved before the RT-call
721 __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size));
722 __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr);
723
724 // load address of JavaThread object for thread-local data
725 NOT_LP64(__ get_thread(thread);)
726 // restore exception oop into rax, (convention for unwind code)
727 __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset()));
728
729 // clear exception fields in JavaThread because they are no longer needed
730 // (fields must be cleared because they are processed by GC otherwise)
731 __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);
732 __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);
733
734 // pop the stub frame off
735 __ leave();
736
737 generate_unwind_exception(sasm);
738 __ stop("should not reach here");
739 } 718 }
740 719
741 720
742 void Runtime1::generate_unwind_exception(StubAssembler *sasm) { 721 void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
743 // incoming parameters 722 // incoming parameters
744 const Register exception_oop = rax; 723 const Register exception_oop = rax;
724 // callee-saved copy of exception_oop during runtime call
725 const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14);
745 // other registers used in this stub 726 // other registers used in this stub
746 const Register exception_pc = rdx; 727 const Register exception_pc = rdx;
747 const Register handler_addr = rbx; 728 const Register handler_addr = rbx;
748 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); 729 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
749 730
767 #endif 748 #endif
768 749
769 // clear the FPU stack in case any FPU results are left behind 750 // clear the FPU stack in case any FPU results are left behind
770 __ empty_FPU_stack(); 751 __ empty_FPU_stack();
771 752
772 // leave activation of nmethod 753 // save exception_oop in callee-saved register to preserve it during runtime calls
773 __ leave(); 754 __ verify_not_null_oop(exception_oop);
774 // store return address (is on top of stack after leave) 755 __ movptr(exception_oop_callee_saved, exception_oop);
756
757 NOT_LP64(__ get_thread(thread);)
758 // Get return address (is on top of stack after leave).
775 __ movptr(exception_pc, Address(rsp, 0)); 759 __ movptr(exception_pc, Address(rsp, 0));
776 760
777 __ verify_oop(exception_oop);
778
779 // save exception oop from rax, to stack before call
780 __ push(exception_oop);
781
782 // search the exception handler address of the caller (using the return address) 761 // search the exception handler address of the caller (using the return address)
783 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc); 762 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
784 // rax,: exception handler address of the caller 763 // rax: exception handler address of the caller
785 764
786 // only rax, is valid at this time, all other registers have been destroyed by the call 765 // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
787 __ invalidate_registers(false, true, true, true, true, true); 766 __ invalidate_registers(false, true, true, true, false, true);
788 767
789 // move result of call into correct register 768 // move result of call into correct register
790 __ movptr(handler_addr, rax); 769 __ movptr(handler_addr, rax);
791 770
792 // restore exception oop in rax, (required convention of exception handler) 771 // Restore exception oop to RAX (required convention of exception handler).
793 __ pop(exception_oop); 772 __ movptr(exception_oop, exception_oop_callee_saved);
794 773
795 __ verify_oop(exception_oop); 774 // verify that there is really a valid exception in rax
775 __ verify_not_null_oop(exception_oop);
796 776
797 // get throwing pc (= return address). 777 // get throwing pc (= return address).
798 // rdx has been destroyed by the call, so it must be set again 778 // rdx has been destroyed by the call, so it must be set again
799 // the pop is also necessary to simulate the effect of a ret(0) 779 // the pop is also necessary to simulate the effect of a ret(0)
800 __ pop(exception_pc); 780 __ pop(exception_pc);
801 781
802 // verify that that there is really a valid exception in rax, 782 // Restore SP from BP if the exception PC is a MethodHandle call site.
803 __ verify_not_null_oop(exception_oop); 783 NOT_LP64(__ get_thread(thread);)
784 __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0);
785 __ cmovptr(Assembler::notEqual, rsp, rbp);
804 786
805 // continue at exception handler (return address removed) 787 // continue at exception handler (return address removed)
806 // note: do *not* remove arguments when unwinding the 788 // note: do *not* remove arguments when unwinding the
807 // activation since the caller assumes having 789 // activation since the caller assumes having
808 // all arguments on the stack when entering the 790 // all arguments on the stack when entering the
809 // runtime to determine the exception handler 791 // runtime to determine the exception handler
810 // (GC happens at call site with arguments!) 792 // (GC happens at call site with arguments!)
811 // rax,: exception oop 793 // rax: exception oop
812 // rdx: throwing pc 794 // rdx: throwing pc
813 // rbx,: exception handler 795 // rbx: exception handler
814 __ jmp(handler_addr); 796 __ jmp(handler_addr);
815 } 797 }
816 798
817 799
818 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { 800 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {