diff -r bb01e3adecb4 -r b2d040a8d375 hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Apr 14 15:30:13 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Apr 15 18:14:49 2010 -0700 @@ -455,6 +455,60 @@ } +// Emit the code to remove the frame from the stack in the exception +// unwind path. +int LIR_Assembler::emit_unwind_handler() { +#ifndef PRODUCT + if (CommentedAssembly) { + _masm->block_comment("Unwind handler"); + } +#endif + + int offset = code_offset(); + + // Fetch the exception from TLS and clear out exception related thread state + __ get_thread(rsi); + __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); + __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); + __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); + + __ bind(_unwind_handler_entry); + __ verify_not_null_oop(rax); + if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { + __ mov(rsi, rax); // Preserve the exception + } + + // Preform needed unlocking + MonitorExitStub* stub = NULL; + if (method()->is_synchronized()) { + monitor_address(0, FrameMap::rax_opr); + stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); + __ unlock_object(rdi, rbx, rax, *stub->entry()); + __ bind(*stub->continuation()); + } + + if (compilation()->env()->dtrace_method_probes()) { + __ movoop(Address(rsp, 0), method()->constant_encoding()); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); + } + + if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { + __ mov(rax, rsi); // Restore the exception + } + + // remove the activation and dispatch to the unwind handler + __ remove_frame(initial_frame_size_in_bytes()); + __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); + + // Emit the slow path assembly + if (stub != NULL) { + stub->emit_code(this); + } + + return offset; +} + + int LIR_Assembler::emit_deopt_handler() { // if the last instruction is a call (typically to do a throw which // is coming at the end after block reordering) the return address @@ -2795,42 +2849,43 @@ } -void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info, bool unwind) { +void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { assert(exceptionOop->as_register() == rax, "must match"); - assert(unwind || exceptionPC->as_register() == rdx, "must match"); + assert(exceptionPC->as_register() == rdx, "must match"); // exception object is not added to oop map by LinearScan // (LinearScan assumes that no oops are in fixed registers) info->add_register_oop(exceptionOop); Runtime1::StubID unwind_id; - if (!unwind) { - // get current pc information - // pc is only needed if the method has an exception handler, the unwind code does not need it. - int pc_for_athrow_offset = __ offset(); - InternalAddress pc_for_athrow(__ pc()); - __ lea(exceptionPC->as_register(), pc_for_athrow); - add_call_info(pc_for_athrow_offset, info); // for exception handler - - __ verify_not_null_oop(rax); - // search an exception handler (rax: exception oop, rdx: throwing pc) - if (compilation()->has_fpu_code()) { - unwind_id = Runtime1::handle_exception_id; - } else { - unwind_id = Runtime1::handle_exception_nofpu_id; - } - __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); + // get current pc information + // pc is only needed if the method has an exception handler, the unwind code does not need it. + int pc_for_athrow_offset = __ offset(); + InternalAddress pc_for_athrow(__ pc()); + __ lea(exceptionPC->as_register(), pc_for_athrow); + add_call_info(pc_for_athrow_offset, info); // for exception handler + + __ verify_not_null_oop(rax); + // search an exception handler (rax: exception oop, rdx: throwing pc) + if (compilation()->has_fpu_code()) { + unwind_id = Runtime1::handle_exception_id; } else { - // remove the activation - __ remove_frame(initial_frame_size_in_bytes()); - __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); + unwind_id = Runtime1::handle_exception_nofpu_id; } + __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); // enough room for two byte trap __ nop(); } +void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { + assert(exceptionOop->as_register() == rax, "must match"); + + __ jmp(_unwind_handler_entry); +} + + void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { // optimized version for linear scan: