提交 eff3a842 编写于 作者: N never

6926979: should simplify catch_inline_exception

Reviewed-by: twisti
上级 23555d74
...@@ -714,8 +714,6 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { ...@@ -714,8 +714,6 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
// iterate through all entries sequentially // iterate through all entries sequentially
for (;!handlers.is_done(); handlers.next()) { for (;!handlers.is_done(); handlers.next()) {
// Do nothing if turned off
if( !DeutschShiffmanExceptions ) break;
ciExceptionHandler* handler = handlers.handler(); ciExceptionHandler* handler = handlers.handler();
if (handler->is_rethrow()) { if (handler->is_rethrow()) {
...@@ -741,46 +739,26 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { ...@@ -741,46 +739,26 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
return; // No more handling to be done here! return; // No more handling to be done here!
} }
// %%% The following logic replicates make_from_klass_unique. // Get the handler's klass
// TO DO: Replace by a subroutine call. Then generalize
// the type check, as noted in the next "%%%" comment.
ciInstanceKlass* klass = handler->catch_klass(); ciInstanceKlass* klass = handler->catch_klass();
if (UseUniqueSubclasses) {
// (We use make_from_klass because it respects UseUniqueSubclasses.) if (!klass->is_loaded()) { // klass is not loaded?
const TypeOopPtr* tp = TypeOopPtr::make_from_klass(klass); // fall through into catch_call_exceptions which will emit a
klass = tp->klass()->as_instance_klass(); // handler with an uncommon trap.
break;
} }
// Get the handler's klass
if (!klass->is_loaded()) // klass is not loaded?
break; // Must call Rethrow!
if (klass->is_interface()) // should not happen, but... if (klass->is_interface()) // should not happen, but...
break; // bail out break; // bail out
// See if the loaded exception klass has no subtypes
if (klass->has_subklass())
break; // Cannot easily do precise test ==> Rethrow
// %%% Now that subclass checking is very fast, we need to rewrite
// this section and remove the option "DeutschShiffmanExceptions".
// The exception processing chain should be a normal typecase pattern,
// with a bailout to the interpreter only in the case of unloaded
// classes. (The bailout should mark the method non-entrant.)
// This rewrite should be placed in GraphKit::, not Parse::.
// Add a dependence; if any subclass added we need to recompile
// %%% should use stronger assert_unique_concrete_subtype instead
if (!klass->is_final()) {
C->dependencies()->assert_leaf_type(klass);
}
// Implement precise test // Check the type of the exception against the catch type
const TypeKlassPtr *tk = TypeKlassPtr::make(klass); const TypeKlassPtr *tk = TypeKlassPtr::make(klass);
Node* con = _gvn.makecon(tk); Node* con = _gvn.makecon(tk);
Node* cmp = _gvn.transform( new (C, 3) CmpPNode(ex_klass_node, con) ); Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con);
Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) ); if (!stopped()) {
{ BuildCutout unless(this, bol, PROB_LIKELY(0.7f)); PreserveJVMState pjvms(this);
const TypeInstPtr* tinst = TypeInstPtr::make_exact(TypePtr::NotNull, klass); const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr();
assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness");
Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst)); Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst));
push_ex_oop(ex_oop); // Push exception oop for handler push_ex_oop(ex_oop); // Push exception oop for handler
#ifndef PRODUCT #ifndef PRODUCT
...@@ -792,6 +770,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { ...@@ -792,6 +770,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
#endif #endif
merge_exception(handler_bci); merge_exception(handler_bci);
} }
set_control(not_subtype_ctrl);
// Come here if exception does not match handler. // Come here if exception does not match handler.
// Carry on with more handler checks. // Carry on with more handler checks.
...@@ -800,21 +779,6 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { ...@@ -800,21 +779,6 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
assert(!stopped(), "you should return if you finish the chain"); assert(!stopped(), "you should return if you finish the chain");
if (remaining == 1) {
// Further checks do not matter.
}
if (can_rerun_bytecode()) {
// Do not push_ex_oop here!
// Re-executing the bytecode will reproduce the throwing condition.
bool must_throw = true;
uncommon_trap(Deoptimization::Reason_unhandled,
Deoptimization::Action_none,
(ciKlass*)NULL, (const char*)NULL, // default args
must_throw);
return;
}
// Oops, need to call into the VM to resolve the klasses at runtime. // Oops, need to call into the VM to resolve the klasses at runtime.
// Note: This call must not deoptimize, since it is not a real at this bci! // Note: This call must not deoptimize, since it is not a real at this bci!
kill_dead_locals(); kill_dead_locals();
......
...@@ -551,9 +551,6 @@ class Parse : public GraphKit { ...@@ -551,9 +551,6 @@ class Parse : public GraphKit {
// Also handles exceptions for individual bytecodes. // Also handles exceptions for individual bytecodes.
void catch_inline_exceptions(SafePointNode* ex_map); void catch_inline_exceptions(SafePointNode* ex_map);
// Bytecode classifier, helps decide to use uncommon_trap vs. rethrow_C.
bool can_rerun_bytecode();
// Merge the given map into correct exceptional exit state. // Merge the given map into correct exceptional exit state.
// Assumes that there is no applicable local handler. // Assumes that there is no applicable local handler.
void throw_to_exit(SafePointNode* ex_map); void throw_to_exit(SafePointNode* ex_map);
......
...@@ -798,67 +798,6 @@ void Compile::rethrow_exceptions(JVMState* jvms) { ...@@ -798,67 +798,6 @@ void Compile::rethrow_exceptions(JVMState* jvms) {
initial_gvn()->transform_no_reclaim(exit); initial_gvn()->transform_no_reclaim(exit);
} }
bool Parse::can_rerun_bytecode() {
switch (bc()) {
case Bytecodes::_ldc:
case Bytecodes::_ldc_w:
case Bytecodes::_ldc2_w:
case Bytecodes::_getfield:
case Bytecodes::_putfield:
case Bytecodes::_getstatic:
case Bytecodes::_putstatic:
case Bytecodes::_arraylength:
case Bytecodes::_baload:
case Bytecodes::_caload:
case Bytecodes::_iaload:
case Bytecodes::_saload:
case Bytecodes::_faload:
case Bytecodes::_aaload:
case Bytecodes::_laload:
case Bytecodes::_daload:
case Bytecodes::_bastore:
case Bytecodes::_castore:
case Bytecodes::_iastore:
case Bytecodes::_sastore:
case Bytecodes::_fastore:
case Bytecodes::_aastore:
case Bytecodes::_lastore:
case Bytecodes::_dastore:
case Bytecodes::_irem:
case Bytecodes::_idiv:
case Bytecodes::_lrem:
case Bytecodes::_ldiv:
case Bytecodes::_frem:
case Bytecodes::_fdiv:
case Bytecodes::_drem:
case Bytecodes::_ddiv:
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
case Bytecodes::_anewarray:
case Bytecodes::_newarray:
case Bytecodes::_multianewarray:
case Bytecodes::_new:
case Bytecodes::_monitorenter: // can re-run initial null check, only
case Bytecodes::_return:
return true;
break;
// Don't rerun athrow since it's part of the exception path.
case Bytecodes::_athrow:
case Bytecodes::_invokestatic:
case Bytecodes::_invokedynamic:
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface:
return false;
break;
default:
assert(false, "unexpected bytecode produced an exception");
return true;
}
}
//---------------------------do_exceptions------------------------------------- //---------------------------do_exceptions-------------------------------------
// Process exceptions arising from the current bytecode. // Process exceptions arising from the current bytecode.
// Send caught exceptions to the proper handler within this method. // Send caught exceptions to the proper handler within this method.
...@@ -872,9 +811,6 @@ void Parse::do_exceptions() { ...@@ -872,9 +811,6 @@ void Parse::do_exceptions() {
return; return;
} }
// Make sure we can classify this bytecode if we need to.
debug_only(can_rerun_bytecode());
PreserveJVMState pjvms(this, false); PreserveJVMState pjvms(this, false);
SafePointNode* ex_map; SafePointNode* ex_map;
......
...@@ -2494,10 +2494,6 @@ class CommandLineFlags { ...@@ -2494,10 +2494,6 @@ class CommandLineFlags {
notproduct(bool, TraceSpilling, false, \ notproduct(bool, TraceSpilling, false, \
"Trace spilling") \ "Trace spilling") \
\ \
develop(bool, DeutschShiffmanExceptions, true, \
"Fast check to find exception handler for precisely typed " \
"exceptions") \
\
product(bool, SplitIfBlocks, true, \ product(bool, SplitIfBlocks, true, \
"Clone compares and control flow through merge points to fold " \ "Clone compares and control flow through merge points to fold " \
"some branches") \ "some branches") \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册