1.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Mon Mar 08 04:46:30 2010 -0800 1.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Tue Mar 09 20:16:19 2010 +0100 1.3 @@ -369,7 +369,7 @@ 1.4 // The pending exception in Thread is converted into a Java-level exception. 1.5 // 1.6 // Contract with Java-level exception handlers: 1.7 - // rax,: exception 1.8 + // rax: exception 1.9 // rdx: throwing pc 1.10 // 1.11 // NOTE: At entry of this stub, exception-pc must be on stack !! 1.12 @@ -377,6 +377,12 @@ 1.13 address generate_forward_exception() { 1.14 StubCodeMark mark(this, "StubRoutines", "forward exception"); 1.15 address start = __ pc(); 1.16 + const Register thread = rcx; 1.17 + 1.18 + // other registers used in this stub 1.19 + const Register exception_oop = rax; 1.20 + const Register handler_addr = rbx; 1.21 + const Register exception_pc = rdx; 1.22 1.23 // Upon entry, the sp points to the return address returning into Java 1.24 // (interpreted or compiled) code; i.e., the return address becomes the 1.25 @@ -389,8 +395,8 @@ 1.26 #ifdef ASSERT 1.27 // make sure this code is only executed if there is a pending exception 1.28 { Label L; 1.29 - __ get_thread(rcx); 1.30 - __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 1.31 + __ get_thread(thread); 1.32 + __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 1.33 __ jcc(Assembler::notEqual, L); 1.34 __ stop("StubRoutines::forward exception: no pending exception (1)"); 1.35 __ bind(L); 1.36 @@ -398,33 +404,40 @@ 1.37 #endif 1.38 1.39 // compute exception handler into rbx, 1.40 - __ movptr(rax, Address(rsp, 0)); 1.41 + __ get_thread(thread); 1.42 + __ movptr(exception_pc, Address(rsp, 0)); 1.43 BLOCK_COMMENT("call exception_handler_for_return_address"); 1.44 - __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax); 1.45 - __ mov(rbx, rax); 1.46 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 1.47 + __ mov(handler_addr, rax); 1.48 1.49 - // setup rax, & rdx, remove return address & clear pending exception 1.50 - __ get_thread(rcx); 1.51 - __ pop(rdx); 1.52 - __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); 1.53 - __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); 1.54 + // setup rax & rdx, remove return address & clear pending exception 1.55 + __ get_thread(thread); 1.56 + __ pop(exception_pc); 1.57 + __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); 1.58 + __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); 1.59 1.60 #ifdef ASSERT 1.61 // make sure exception is set 1.62 { Label L; 1.63 - __ testptr(rax, rax); 1.64 + __ testptr(exception_oop, exception_oop); 1.65 __ jcc(Assembler::notEqual, L); 1.66 __ stop("StubRoutines::forward exception: no pending exception (2)"); 1.67 __ bind(L); 1.68 } 1.69 #endif 1.70 1.71 + // Verify that there is really a valid exception in RAX. 1.72 + __ verify_oop(exception_oop); 1.73 + 1.74 + // Restore SP from BP if the exception PC is a MethodHandle call site. 1.75 + __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0); 1.76 + __ cmovptr(Assembler::notEqual, rsp, rbp); 1.77 + 1.78 // continue at exception handler (return address removed) 1.79 - // rax,: exception 1.80 - // rbx,: exception handler 1.81 + // rax: exception 1.82 + // rbx: exception handler 1.83 // rdx: throwing pc 1.84 - __ verify_oop(rax); 1.85 - __ jmp(rbx); 1.86 + __ jmp(handler_addr); 1.87 1.88 return start; 1.89 }