6926979: should simplify catch_inline_exception

Thu, 18 Mar 2010 14:31:41 -0700

author
never
date
Thu, 18 Mar 2010 14:31:41 -0700
changeset 1779
fdd57634910e
parent 1740
97fe2cc98b1d
child 1780
747d26efc5fa

6926979: should simplify catch_inline_exception
Reviewed-by: twisti

src/share/vm/opto/doCall.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parse.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parse1.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/doCall.cpp	Thu Mar 18 06:36:43 2010 -0700
     1.2 +++ b/src/share/vm/opto/doCall.cpp	Thu Mar 18 14:31:41 2010 -0700
     1.3 @@ -714,8 +714,6 @@
     1.4  
     1.5    // iterate through all entries sequentially
     1.6    for (;!handlers.is_done(); handlers.next()) {
     1.7 -    // Do nothing if turned off
     1.8 -    if( !DeutschShiffmanExceptions ) break;
     1.9      ciExceptionHandler* handler = handlers.handler();
    1.10  
    1.11      if (handler->is_rethrow()) {
    1.12 @@ -741,46 +739,26 @@
    1.13        return;                   // No more handling to be done here!
    1.14      }
    1.15  
    1.16 -    // %%% The following logic replicates make_from_klass_unique.
    1.17 -    // TO DO:  Replace by a subroutine call.  Then generalize
    1.18 -    // the type check, as noted in the next "%%%" comment.
    1.19 +    // Get the handler's klass
    1.20 +    ciInstanceKlass* klass = handler->catch_klass();
    1.21  
    1.22 -    ciInstanceKlass* klass = handler->catch_klass();
    1.23 -    if (UseUniqueSubclasses) {
    1.24 -      // (We use make_from_klass because it respects UseUniqueSubclasses.)
    1.25 -      const TypeOopPtr* tp = TypeOopPtr::make_from_klass(klass);
    1.26 -      klass = tp->klass()->as_instance_klass();
    1.27 +    if (!klass->is_loaded()) {  // klass is not loaded?
    1.28 +      // fall through into catch_call_exceptions which will emit a
    1.29 +      // handler with an uncommon trap.
    1.30 +      break;
    1.31      }
    1.32  
    1.33 -    // Get the handler's klass
    1.34 -    if (!klass->is_loaded())    // klass is not loaded?
    1.35 -      break;                    // Must call Rethrow!
    1.36      if (klass->is_interface())  // should not happen, but...
    1.37        break;                    // bail out
    1.38 -    // See if the loaded exception klass has no subtypes
    1.39 -    if (klass->has_subklass())
    1.40 -      break;                    // Cannot easily do precise test ==> Rethrow
    1.41  
    1.42 -    // %%% Now that subclass checking is very fast, we need to rewrite
    1.43 -    // this section and remove the option "DeutschShiffmanExceptions".
    1.44 -    // The exception processing chain should be a normal typecase pattern,
    1.45 -    // with a bailout to the interpreter only in the case of unloaded
    1.46 -    // classes.  (The bailout should mark the method non-entrant.)
    1.47 -    // This rewrite should be placed in GraphKit::, not Parse::.
    1.48 -
    1.49 -    // Add a dependence; if any subclass added we need to recompile
    1.50 -    // %%% should use stronger assert_unique_concrete_subtype instead
    1.51 -    if (!klass->is_final()) {
    1.52 -      C->dependencies()->assert_leaf_type(klass);
    1.53 -    }
    1.54 -
    1.55 -    // Implement precise test
    1.56 +    // Check the type of the exception against the catch type
    1.57      const TypeKlassPtr *tk = TypeKlassPtr::make(klass);
    1.58      Node* con = _gvn.makecon(tk);
    1.59 -    Node* cmp = _gvn.transform( new (C, 3) CmpPNode(ex_klass_node, con) );
    1.60 -    Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) );
    1.61 -    { BuildCutout unless(this, bol, PROB_LIKELY(0.7f));
    1.62 -      const TypeInstPtr* tinst = TypeInstPtr::make_exact(TypePtr::NotNull, klass);
    1.63 +    Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con);
    1.64 +    if (!stopped()) {
    1.65 +      PreserveJVMState pjvms(this);
    1.66 +      const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr();
    1.67 +      assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness");
    1.68        Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst));
    1.69        push_ex_oop(ex_oop);      // Push exception oop for handler
    1.70  #ifndef PRODUCT
    1.71 @@ -792,6 +770,7 @@
    1.72  #endif
    1.73        merge_exception(handler_bci);
    1.74      }
    1.75 +    set_control(not_subtype_ctrl);
    1.76  
    1.77      // Come here if exception does not match handler.
    1.78      // Carry on with more handler checks.
    1.79 @@ -800,21 +779,6 @@
    1.80  
    1.81    assert(!stopped(), "you should return if you finish the chain");
    1.82  
    1.83 -  if (remaining == 1) {
    1.84 -    // Further checks do not matter.
    1.85 -  }
    1.86 -
    1.87 -  if (can_rerun_bytecode()) {
    1.88 -    // Do not push_ex_oop here!
    1.89 -    // Re-executing the bytecode will reproduce the throwing condition.
    1.90 -    bool must_throw = true;
    1.91 -    uncommon_trap(Deoptimization::Reason_unhandled,
    1.92 -                  Deoptimization::Action_none,
    1.93 -                  (ciKlass*)NULL, (const char*)NULL, // default args
    1.94 -                  must_throw);
    1.95 -    return;
    1.96 -  }
    1.97 -
    1.98    // Oops, need to call into the VM to resolve the klasses at runtime.
    1.99    // Note:  This call must not deoptimize, since it is not a real at this bci!
   1.100    kill_dead_locals();
     2.1 --- a/src/share/vm/opto/parse.hpp	Thu Mar 18 06:36:43 2010 -0700
     2.2 +++ b/src/share/vm/opto/parse.hpp	Thu Mar 18 14:31:41 2010 -0700
     2.3 @@ -551,9 +551,6 @@
     2.4    // Also handles exceptions for individual bytecodes.
     2.5    void catch_inline_exceptions(SafePointNode* ex_map);
     2.6  
     2.7 -  // Bytecode classifier, helps decide to use uncommon_trap vs. rethrow_C.
     2.8 -  bool can_rerun_bytecode();
     2.9 -
    2.10    // Merge the given map into correct exceptional exit state.
    2.11    // Assumes that there is no applicable local handler.
    2.12    void throw_to_exit(SafePointNode* ex_map);
     3.1 --- a/src/share/vm/opto/parse1.cpp	Thu Mar 18 06:36:43 2010 -0700
     3.2 +++ b/src/share/vm/opto/parse1.cpp	Thu Mar 18 14:31:41 2010 -0700
     3.3 @@ -798,67 +798,6 @@
     3.4    initial_gvn()->transform_no_reclaim(exit);
     3.5  }
     3.6  
     3.7 -bool Parse::can_rerun_bytecode() {
     3.8 -  switch (bc()) {
     3.9 -  case Bytecodes::_ldc:
    3.10 -  case Bytecodes::_ldc_w:
    3.11 -  case Bytecodes::_ldc2_w:
    3.12 -  case Bytecodes::_getfield:
    3.13 -  case Bytecodes::_putfield:
    3.14 -  case Bytecodes::_getstatic:
    3.15 -  case Bytecodes::_putstatic:
    3.16 -  case Bytecodes::_arraylength:
    3.17 -  case Bytecodes::_baload:
    3.18 -  case Bytecodes::_caload:
    3.19 -  case Bytecodes::_iaload:
    3.20 -  case Bytecodes::_saload:
    3.21 -  case Bytecodes::_faload:
    3.22 -  case Bytecodes::_aaload:
    3.23 -  case Bytecodes::_laload:
    3.24 -  case Bytecodes::_daload:
    3.25 -  case Bytecodes::_bastore:
    3.26 -  case Bytecodes::_castore:
    3.27 -  case Bytecodes::_iastore:
    3.28 -  case Bytecodes::_sastore:
    3.29 -  case Bytecodes::_fastore:
    3.30 -  case Bytecodes::_aastore:
    3.31 -  case Bytecodes::_lastore:
    3.32 -  case Bytecodes::_dastore:
    3.33 -  case Bytecodes::_irem:
    3.34 -  case Bytecodes::_idiv:
    3.35 -  case Bytecodes::_lrem:
    3.36 -  case Bytecodes::_ldiv:
    3.37 -  case Bytecodes::_frem:
    3.38 -  case Bytecodes::_fdiv:
    3.39 -  case Bytecodes::_drem:
    3.40 -  case Bytecodes::_ddiv:
    3.41 -  case Bytecodes::_checkcast:
    3.42 -  case Bytecodes::_instanceof:
    3.43 -  case Bytecodes::_anewarray:
    3.44 -  case Bytecodes::_newarray:
    3.45 -  case Bytecodes::_multianewarray:
    3.46 -  case Bytecodes::_new:
    3.47 -  case Bytecodes::_monitorenter:  // can re-run initial null check, only
    3.48 -  case Bytecodes::_return:
    3.49 -    return true;
    3.50 -    break;
    3.51 -
    3.52 -  // Don't rerun athrow since it's part of the exception path.
    3.53 -  case Bytecodes::_athrow:
    3.54 -  case Bytecodes::_invokestatic:
    3.55 -  case Bytecodes::_invokedynamic:
    3.56 -  case Bytecodes::_invokespecial:
    3.57 -  case Bytecodes::_invokevirtual:
    3.58 -  case Bytecodes::_invokeinterface:
    3.59 -    return false;
    3.60 -    break;
    3.61 -
    3.62 -  default:
    3.63 -    assert(false, "unexpected bytecode produced an exception");
    3.64 -    return true;
    3.65 -  }
    3.66 -}
    3.67 -
    3.68  //---------------------------do_exceptions-------------------------------------
    3.69  // Process exceptions arising from the current bytecode.
    3.70  // Send caught exceptions to the proper handler within this method.
    3.71 @@ -872,9 +811,6 @@
    3.72      return;
    3.73    }
    3.74  
    3.75 -  // Make sure we can classify this bytecode if we need to.
    3.76 -  debug_only(can_rerun_bytecode());
    3.77 -
    3.78    PreserveJVMState pjvms(this, false);
    3.79  
    3.80    SafePointNode* ex_map;
     4.1 --- a/src/share/vm/runtime/globals.hpp	Thu Mar 18 06:36:43 2010 -0700
     4.2 +++ b/src/share/vm/runtime/globals.hpp	Thu Mar 18 14:31:41 2010 -0700
     4.3 @@ -2494,10 +2494,6 @@
     4.4    notproduct(bool, TraceSpilling, false,                                    \
     4.5            "Trace spilling")                                                 \
     4.6                                                                              \
     4.7 -  develop(bool, DeutschShiffmanExceptions, true,                            \
     4.8 -          "Fast check to find exception handler for precisely typed "       \
     4.9 -          "exceptions")                                                     \
    4.10 -                                                                            \
    4.11    product(bool, SplitIfBlocks, true,                                        \
    4.12            "Clone compares and control flow through merge points to fold "   \
    4.13            "some branches")                                                  \

mercurial