--- 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: