src/cpu/x86/vm/c1_Runtime1_x86.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6919934 Cdiff src/cpu/x86/vm/c1_Runtime1_x86.cpp
src/cpu/x86/vm/c1_Runtime1_x86.cpp
Print this page
*** 686,707 ****
// compute the exception handler.
// the exception oop and the throwing pc are read from the fields in JavaThread
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
oop_maps->add_gc_map(call_offset, oop_map);
! // rax,: handler address or NULL if no handler exists
// will be the deopt blob if nmethod was deoptimized while we looked up
// handler regardless of whether handler existed in the nmethod.
// only rax, is valid at this time, all other registers have been destroyed by the runtime call
__ invalidate_registers(false, true, true, true, true, true);
// Do we have an exception handler in the nmethod?
- Label no_handler;
Label done;
__ testptr(rax, rax);
! __ jcc(Assembler::zero, no_handler);
// exception handler found
// patch the return address -> the stub will directly return to the exception handler
__ movptr(Address(rbp, 1*BytesPerWord), rax);
--- 686,710 ----
// compute the exception handler.
// the exception oop and the throwing pc are read from the fields in JavaThread
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
oop_maps->add_gc_map(call_offset, oop_map);
! // rax,: handler address
// will be the deopt blob if nmethod was deoptimized while we looked up
// handler regardless of whether handler existed in the nmethod.
// only rax, is valid at this time, all other registers have been destroyed by the runtime call
__ invalidate_registers(false, true, true, true, true, true);
+ #ifdef ASSERT
// Do we have an exception handler in the nmethod?
Label done;
__ testptr(rax, rax);
! __ jcc(Assembler::notZero, done);
! __ stop("no handler found");
! __ bind(done);
! #endif
// exception handler found
// patch the return address -> the stub will directly return to the exception handler
__ movptr(Address(rbp, 1*BytesPerWord), rax);
*** 710,749 ****
// return to exception handler
__ leave();
__ ret(0);
- __ bind(no_handler);
- // no exception handler found in this method, so the exception is
- // forwarded to the caller (using the unwind code of the nmethod)
- // there is no need to restore the registers
-
- // restore the real return address that was saved before the RT-call
- __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size));
- __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr);
-
- // load address of JavaThread object for thread-local data
- NOT_LP64(__ get_thread(thread);)
- // restore exception oop into rax, (convention for unwind code)
- __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset()));
-
- // clear exception fields in JavaThread because they are no longer needed
- // (fields must be cleared because they are processed by GC otherwise)
- __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);
- __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);
-
- // pop the stub frame off
- __ leave();
-
- generate_unwind_exception(sasm);
- __ stop("should not reach here");
}
void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
// incoming parameters
const Register exception_oop = rax;
// other registers used in this stub
const Register exception_pc = rdx;
const Register handler_addr = rbx;
const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
--- 713,730 ----
// return to exception handler
__ leave();
__ ret(0);
}
void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
// incoming parameters
const Register exception_oop = rax;
+ // callee-saved copy of exception_oop during runtime call
+ const Register exception_oop_callee_saved = NOT_LP64(rsi);
// other registers used in this stub
const Register exception_pc = rdx;
const Register handler_addr = rbx;
const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
*** 767,818 ****
#endif
// clear the FPU stack in case any FPU results are left behind
__ empty_FPU_stack();
! // leave activation of nmethod
! __ leave();
! // store return address (is on top of stack after leave)
! __ movptr(exception_pc, Address(rsp, 0));
!
! __ verify_oop(exception_oop);
! // save exception oop from rax, to stack before call
! __ push(exception_oop);
// search the exception handler address of the caller (using the return address)
! __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc);
! // rax,: exception handler address of the caller
! // only rax, is valid at this time, all other registers have been destroyed by the call
! __ invalidate_registers(false, true, true, true, true, true);
// move result of call into correct register
__ movptr(handler_addr, rax);
! // restore exception oop in rax, (required convention of exception handler)
! __ pop(exception_oop);
! __ verify_oop(exception_oop);
// get throwing pc (= return address).
// rdx has been destroyed by the call, so it must be set again
// the pop is also necessary to simulate the effect of a ret(0)
__ pop(exception_pc);
! // verify that that there is really a valid exception in rax,
! __ verify_not_null_oop(exception_oop);
// continue at exception handler (return address removed)
// note: do *not* remove arguments when unwinding the
// activation since the caller assumes having
// all arguments on the stack when entering the
// runtime to determine the exception handler
// (GC happens at call site with arguments!)
! // rax,: exception oop
// rdx: throwing pc
! // rbx,: exception handler
__ jmp(handler_addr);
}
OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
--- 748,800 ----
#endif
// clear the FPU stack in case any FPU results are left behind
__ empty_FPU_stack();
! // save exception_oop in callee-saved register to preserve it during runtime calls
! __ verify_not_null_oop(exception_oop);
! __ movptr(exception_oop_callee_saved, exception_oop);
! NOT_LP64(__ get_thread(thread);)
! // Get return address (is on top of stack after leave).
! __ movptr(exception_pc, Address(rsp, 0));
// search the exception handler address of the caller (using the return address)
! __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
! // rax: exception handler address of the caller
! // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
! __ invalidate_registers(false, true, true, true, false, true);
// move result of call into correct register
__ movptr(handler_addr, rax);
! // Restore exception oop to RAX (required convention of exception handler).
! __ movptr(exception_oop, exception_oop_callee_saved);
! // verify that there is really a valid exception in rax
! __ verify_not_null_oop(exception_oop);
// get throwing pc (= return address).
// rdx has been destroyed by the call, so it must be set again
// the pop is also necessary to simulate the effect of a ret(0)
__ pop(exception_pc);
! // Restore SP from BP if the exception PC is a MethodHandle call site.
! NOT_LP64(__ get_thread(thread);)
! __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0);
! __ cmovptr(Assembler::notEqual, rsp, rbp);
// continue at exception handler (return address removed)
// note: do *not* remove arguments when unwinding the
// activation since the caller assumes having
// all arguments on the stack when entering the
// runtime to determine the exception handler
// (GC happens at call site with arguments!)
! // rax: exception oop
// rdx: throwing pc
! // rbx: exception handler
__ jmp(handler_addr);
}
OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
src/cpu/x86/vm/c1_Runtime1_x86.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File