Mercurial > hg > graal-compiler
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) { |