# HG changeset patch # User never # Date 1268947901 25200 # Node ID fdd57634910e3cadb86b19b56a22e75c6de0192c # Parent 97fe2cc98b1daab3d19cafa4e69d6df01e9570f8 6926979: should simplify catch_inline_exception Reviewed-by: twisti diff -r 97fe2cc98b1d -r fdd57634910e src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Thu Mar 18 06:36:43 2010 -0700 +++ b/src/share/vm/opto/doCall.cpp Thu Mar 18 14:31:41 2010 -0700 @@ -714,8 +714,6 @@ // iterate through all entries sequentially for (;!handlers.is_done(); handlers.next()) { - // Do nothing if turned off - if( !DeutschShiffmanExceptions ) break; ciExceptionHandler* handler = handlers.handler(); if (handler->is_rethrow()) { @@ -741,46 +739,26 @@ return; // No more handling to be done here! } - // %%% The following logic replicates make_from_klass_unique. - // TO DO: Replace by a subroutine call. Then generalize - // the type check, as noted in the next "%%%" comment. - + // Get the handler's klass ciInstanceKlass* klass = handler->catch_klass(); - if (UseUniqueSubclasses) { - // (We use make_from_klass because it respects UseUniqueSubclasses.) - const TypeOopPtr* tp = TypeOopPtr::make_from_klass(klass); - klass = tp->klass()->as_instance_klass(); + + if (!klass->is_loaded()) { // klass is not loaded? + // fall through into catch_call_exceptions which will emit a + // 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... 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); Node* con = _gvn.makecon(tk); - Node* cmp = _gvn.transform( new (C, 3) CmpPNode(ex_klass_node, con) ); - Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) ); - { BuildCutout unless(this, bol, PROB_LIKELY(0.7f)); - const TypeInstPtr* tinst = TypeInstPtr::make_exact(TypePtr::NotNull, klass); + Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con); + if (!stopped()) { + PreserveJVMState pjvms(this); + 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)); push_ex_oop(ex_oop); // Push exception oop for handler #ifndef PRODUCT @@ -792,6 +770,7 @@ #endif merge_exception(handler_bci); } + set_control(not_subtype_ctrl); // Come here if exception does not match handler. // Carry on with more handler checks. @@ -800,21 +779,6 @@ 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. // Note: This call must not deoptimize, since it is not a real at this bci! kill_dead_locals(); diff -r 97fe2cc98b1d -r fdd57634910e src/share/vm/opto/parse.hpp --- a/src/share/vm/opto/parse.hpp Thu Mar 18 06:36:43 2010 -0700 +++ b/src/share/vm/opto/parse.hpp Thu Mar 18 14:31:41 2010 -0700 @@ -551,9 +551,6 @@ // Also handles exceptions for individual bytecodes. 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. // Assumes that there is no applicable local handler. void throw_to_exit(SafePointNode* ex_map); diff -r 97fe2cc98b1d -r fdd57634910e src/share/vm/opto/parse1.cpp --- a/src/share/vm/opto/parse1.cpp Thu Mar 18 06:36:43 2010 -0700 +++ b/src/share/vm/opto/parse1.cpp Thu Mar 18 14:31:41 2010 -0700 @@ -798,67 +798,6 @@ 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------------------------------------- // Process exceptions arising from the current bytecode. // Send caught exceptions to the proper handler within this method. @@ -872,9 +811,6 @@ return; } - // Make sure we can classify this bytecode if we need to. - debug_only(can_rerun_bytecode()); - PreserveJVMState pjvms(this, false); SafePointNode* ex_map; diff -r 97fe2cc98b1d -r fdd57634910e src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu Mar 18 06:36:43 2010 -0700 +++ b/src/share/vm/runtime/globals.hpp Thu Mar 18 14:31:41 2010 -0700 @@ -2494,10 +2494,6 @@ notproduct(bool, TraceSpilling, false, \ "Trace spilling") \ \ - develop(bool, DeutschShiffmanExceptions, true, \ - "Fast check to find exception handler for precisely typed " \ - "exceptions") \ - \ product(bool, SplitIfBlocks, true, \ "Clone compares and control flow through merge points to fold " \ "some branches") \