6939930: exception unwind changes in 6919934 hurts compilation speed
Reviewed-by: twisti
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -388,6 +388,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
+ __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), O0);
+ __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
+ __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
+
+ __ bind(_unwind_handler_entry);
+ __ verify_not_null_oop(O0);
+ if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
+ __ mov(O0, I0); // Preserve the exception
+ }
+
+ // Preform needed unlocking
+ MonitorExitStub* stub = NULL;
+ if (method()->is_synchronized()) {
+ monitor_address(0, FrameMap::I1_opr);
+ stub = new MonitorExitStub(FrameMap::I1_opr, true, 0);
+ __ unlock_object(I3, I2, I1, *stub->entry());
+ __ bind(*stub->continuation());
+ }
+
+ if (compilation()->env()->dtrace_method_probes()) {
+ jobject2reg(method()->constant_encoding(), O0);
+ __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), relocInfo::runtime_call_type);
+ __ delayed()->nop();
+ }
+
+ if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
+ __ mov(I0, O0); // Restore the exception
+ }
+
+ // dispatch to the unwind logic
+ __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type);
+ __ delayed()->nop();
+
+ // 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
@@ -2050,26 +2104,29 @@
}
-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() == Oexception, "should match");
- assert(unwind || exceptionPC->as_register() == Oissuing_pc, "should match");
+ assert(exceptionPC->as_register() == Oissuing_pc, "should match");
info->add_register_oop(exceptionOop);
- if (unwind) {
- __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type);
- __ delayed()->nop();
- } else {
- // reuse the debug info from the safepoint poll for the throw op itself
- address pc_for_athrow = __ pc();
- int pc_for_athrow_offset = __ offset();
- RelocationHolder rspec = internal_word_Relocation::spec(pc_for_athrow);
- __ set(pc_for_athrow, Oissuing_pc, rspec);
- add_call_info(pc_for_athrow_offset, info); // for exception handler
-
- __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
- __ delayed()->nop();
- }
+ // reuse the debug info from the safepoint poll for the throw op itself
+ address pc_for_athrow = __ pc();
+ int pc_for_athrow_offset = __ offset();
+ RelocationHolder rspec = internal_word_Relocation::spec(pc_for_athrow);
+ __ set(pc_for_athrow, Oissuing_pc, rspec);
+ add_call_info(pc_for_athrow_offset, info); // for exception handler
+
+ __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
+ __ delayed()->nop();
+}
+
+
+void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {
+ assert(exceptionOop->as_register() == Oexception, "should match");
+
+ __ br(Assembler::always, false, Assembler::pt, _unwind_handler_entry);
+ __ delayed()->nop();
}
@@ -2358,7 +2415,7 @@
if (UseSlowPath ||
(!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
(!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
- __ br(Assembler::always, false, Assembler::pn, *op->stub()->entry());
+ __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry());
__ delayed()->nop();
} else {
__ allocate_array(op->obj()->as_register(),
--- 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:
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Thu Apr 15 18:14:49 2010 -0700
@@ -40,6 +40,7 @@
Exceptions, // Offset where exception handler lives
Deopt, // Offset where deopt handler lives
DeoptMH, // Offset where MethodHandle deopt handler lives
+ UnwindHandler, // Offset to default unwind handler
max_Entries };
// special value to note codeBlobs where profile (forte) stack walking is
@@ -59,6 +60,7 @@
_values[Exceptions ] = -1;
_values[Deopt ] = -1;
_values[DeoptMH ] = -1;
+ _values[UnwindHandler ] = -1;
}
int value(Entries e) { return _values[e]; }
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -229,6 +229,10 @@
code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler());
CHECK_BAILOUT();
+ // Emit the handler to remove the activation from the stack and
+ // dispatch to the caller.
+ offsets()->set_value(CodeOffsets::UnwindHandler, assembler->emit_unwind_handler());
+
// done
masm()->flush();
}
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -829,12 +829,8 @@
// should be left alone since there can be only one and all code
// should dispatch to the same one.
XHandler* h = handlers->handler_at(i);
- if (h->handler_bci() != SynchronizationEntryBCI) {
- h->set_entry_block(block_at(h->handler_bci()));
- } else {
- assert(h->entry_block()->is_set(BlockBegin::default_exception_handler_flag),
- "should be the synthetic unlock block");
- }
+ assert(h->handler_bci() != SynchronizationEntryBCI, "must be real");
+ h->set_entry_block(block_at(h->handler_bci()));
}
_jsr_xhandlers = handlers;
}
@@ -2867,19 +2863,6 @@
_initial_state = state_at_entry();
start_block->merge(_initial_state);
- // setup an exception handler to do the unlocking and/or
- // notification and unwind the frame.
- BlockBegin* sync_handler = new BlockBegin(-1);
- sync_handler->set(BlockBegin::exception_entry_flag);
- sync_handler->set(BlockBegin::is_on_work_list_flag);
- sync_handler->set(BlockBegin::default_exception_handler_flag);
-
- ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
- XHandler* h = new XHandler(desc);
- h->set_entry_block(sync_handler);
- scope_data()->xhandlers()->append(h);
- scope_data()->set_has_handler();
-
// complete graph
_vmap = new ValueMap();
scope->compute_lock_stack_size();
@@ -2930,19 +2913,6 @@
}
CHECK_BAILOUT();
- if (sync_handler && sync_handler->state() != NULL) {
- Value lock = NULL;
- if (method()->is_synchronized()) {
- lock = method()->is_static() ? new Constant(new InstanceConstant(method()->holder()->java_mirror())) :
- _initial_state->local_at(0);
-
- sync_handler->state()->unlock();
- sync_handler->state()->lock(scope, lock);
-
- }
- fill_sync_handler(lock, sync_handler, true);
- }
-
_start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
eliminate_redundant_phis(_start);
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Thu Apr 15 18:14:49 2010 -0700
@@ -1628,11 +1628,10 @@
backward_branch_target_flag = 1 << 4,
is_on_work_list_flag = 1 << 5,
was_visited_flag = 1 << 6,
- default_exception_handler_flag = 1 << 8, // identify block which represents the default exception handler
- parser_loop_header_flag = 1 << 9, // set by parser to identify blocks where phi functions can not be created on demand
- critical_edge_split_flag = 1 << 10, // set for all blocks that are introduced when critical edges are split
- linear_scan_loop_header_flag = 1 << 11, // set during loop-detection for LinearScan
- linear_scan_loop_end_flag = 1 << 12 // set during loop-detection for LinearScan
+ parser_loop_header_flag = 1 << 7, // set by parser to identify blocks where phi functions can not be created on demand
+ critical_edge_split_flag = 1 << 8, // set for all blocks that are introduced when critical edges are split
+ linear_scan_loop_header_flag = 1 << 9, // set during loop-detection for LinearScan
+ linear_scan_loop_end_flag = 1 << 10 // set during loop-detection for LinearScan
};
void set(Flag f) { _flags |= f; }
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -626,8 +626,7 @@
break;
}
- case lir_throw:
- case lir_unwind: {
+ case lir_throw: {
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
@@ -639,6 +638,17 @@
break;
}
+ case lir_unwind: {
+ assert(op->as_Op1() != NULL, "must be");
+ LIR_Op1* op1 = (LIR_Op1*)op;
+
+ assert(op1->_info == NULL, "no info");
+ assert(op1->_opr->is_valid(), "exception oop"); do_input(op1->_opr);
+ assert(op1->_result->is_illegal(), "no result");
+
+ break;
+ }
+
case lir_tan:
case lir_sin:
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Apr 15 18:14:49 2010 -0700
@@ -801,6 +801,7 @@
, lir_monaddr
, lir_roundfp
, lir_safepoint
+ , lir_unwind
, end_op1
, begin_op2
, lir_cmp
@@ -830,7 +831,6 @@
, lir_ushr
, lir_alloc_array
, lir_throw
- , lir_unwind
, lir_compare_to
, end_op2
, begin_op3
@@ -1827,8 +1827,12 @@
void logical_xor (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_xor, left, right, dst)); }
void null_check(LIR_Opr opr, CodeEmitInfo* info) { append(new LIR_Op1(lir_null_check, opr, info)); }
- void throw_exception(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { append(new LIR_Op2(lir_throw, exceptionPC, exceptionOop, LIR_OprFact::illegalOpr, info)); }
- void unwind_exception(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { append(new LIR_Op2(lir_unwind, exceptionPC, exceptionOop, LIR_OprFact::illegalOpr, info)); }
+ void throw_exception(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {
+ append(new LIR_Op2(lir_throw, exceptionPC, exceptionOop, LIR_OprFact::illegalOpr, info));
+ }
+ void unwind_exception(LIR_Opr exceptionOop) {
+ append(new LIR_Op1(lir_unwind, exceptionOop));
+ }
void compare_to (LIR_Opr left, LIR_Opr right, LIR_Opr dst) {
append(new LIR_Op2(lir_compare_to, left, right, dst));
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -552,6 +552,10 @@
monitor_address(op->in_opr()->as_constant_ptr()->as_jint(), op->result_opr());
break;
+ case lir_unwind:
+ unwind_op(op->in_opr());
+ break;
+
default:
Unimplemented();
break;
@@ -707,8 +711,7 @@
break;
case lir_throw:
- case lir_unwind:
- throw_op(op->in_opr1(), op->in_opr2(), op->info(), op->code() == lir_unwind);
+ throw_op(op->in_opr1(), op->in_opr2(), op->info());
break;
default:
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Apr 15 18:14:49 2010 -0700
@@ -39,6 +39,8 @@
Instruction* _pending_non_safepoint;
int _pending_non_safepoint_offset;
+ Label _unwind_handler_entry;
+
#ifdef ASSERT
BlockList _branch_target_blocks;
void check_no_unbound_labels();
@@ -134,6 +136,7 @@
// code patterns
int emit_exception_handler();
+ int emit_unwind_handler();
void emit_exception_entries(ExceptionInfoList* info_list);
int emit_deopt_handler();
@@ -217,7 +220,8 @@
void build_frame();
- void throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info, bool unwind);
+ void throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info);
+ void unwind_op(LIR_Opr exceptionOop);
void monitor_address(int monitor_ix, LIR_Opr dst);
void align_backward_branch_target();
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -1765,35 +1765,17 @@
__ null_check(exception_opr, new CodeEmitInfo(info, true));
}
- if (compilation()->env()->jvmti_can_post_on_exceptions() &&
- !block()->is_set(BlockBegin::default_exception_handler_flag)) {
+ if (compilation()->env()->jvmti_can_post_on_exceptions()) {
// we need to go through the exception lookup path to get JVMTI
// notification done
unwind = false;
}
- assert(!block()->is_set(BlockBegin::default_exception_handler_flag) || unwind,
- "should be no more handlers to dispatch to");
-
- if (compilation()->env()->dtrace_method_probes() &&
- block()->is_set(BlockBegin::default_exception_handler_flag)) {
- // notify that this frame is unwinding
- BasicTypeList signature;
- signature.append(T_INT); // thread
- signature.append(T_OBJECT); // methodOop
- LIR_OprList* args = new LIR_OprList();
- args->append(getThreadPointer());
- LIR_Opr meth = new_register(T_OBJECT);
- __ oop2reg(method()->constant_encoding(), meth);
- args->append(meth);
- call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
- }
-
// move exception oop into fixed register
__ move(exception_opr, exceptionOopOpr());
if (unwind) {
- __ unwind_exception(LIR_OprFact::illegalOpr, exceptionOopOpr(), info);
+ __ unwind_exception(exceptionOopOpr());
} else {
__ throw_exception(exceptionPcOpr(), exceptionOopOpr(), info);
}
--- a/hotspot/src/share/vm/code/nmethod.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -685,6 +685,7 @@
_exception_offset = 0;
_deoptimize_offset = 0;
_deoptimize_mh_offset = 0;
+ _unwind_handler_offset = -1;
_trap_offset = offsets->value(CodeOffsets::Dtrace_trap);
_orig_pc_offset = 0;
_stub_offset = data_offset();
@@ -798,6 +799,11 @@
_exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions);
_deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt);
_deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH);
+ if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
+ _unwind_handler_offset = instructions_offset() + offsets->value(CodeOffsets::UnwindHandler);
+ } else {
+ _unwind_handler_offset = -1;
+ }
_consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
_scopes_data_offset = data_offset();
_scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
--- a/hotspot/src/share/vm/code/nmethod.hpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp Thu Apr 15 18:14:49 2010 -0700
@@ -154,6 +154,9 @@
// All deoptee's at a MethodHandle call site will resume execution
// at this location described by this offset.
int _deoptimize_mh_offset;
+ // Offset of the unwind handler if it exists
+ int _unwind_handler_offset;
+
#ifdef HAVE_DTRACE_H
int _trap_offset;
#endif // def HAVE_DTRACE_H
@@ -341,6 +344,7 @@
address exception_begin () const { return header_begin() + _exception_offset ; }
address deopt_handler_begin () const { return header_begin() + _deoptimize_offset ; }
address deopt_mh_handler_begin() const { return header_begin() + _deoptimize_mh_offset ; }
+ address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
address stub_begin () const { return header_begin() + _stub_offset ; }
address stub_end () const { return header_begin() + _consts_offset ; }
address consts_begin () const { return header_begin() + _consts_offset ; }
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Apr 14 15:30:13 2010 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Apr 15 18:14:49 2010 -0700
@@ -473,6 +473,13 @@
t = table.entry_for(catch_pco, -1, 0);
}
+#ifdef COMPILER1
+ if (t == NULL && nm->is_compiled_by_c1()) {
+ assert(nm->unwind_handler_begin() != NULL, "");
+ return nm->unwind_handler_begin();
+ }
+#endif
+
if (t == NULL) {
tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci);
tty->print_cr(" Exception:");