8074548: Never-taken branches cause repeated deopts in MHs.GWT case

Fri, 20 Mar 2015 11:41:34 -0700

author
vlivanov
date
Fri, 20 Mar 2015 11:41:34 -0700
changeset 7790
d9593687713d
parent 7789
eb8b5cc64669
child 7791
4eeec0cdeb6a

8074548: Never-taken branches cause repeated deopts in MHs.GWT case
Reviewed-by: jrose, kvn

src/share/vm/opto/library_call.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/library_call.cpp	Thu Jan 29 10:25:59 2015 -0800
     1.2 +++ b/src/share/vm/opto/library_call.cpp	Fri Mar 20 11:41:34 2015 -0700
     1.3 @@ -6576,12 +6576,46 @@
     1.4                            Deoptimization::Action_reinterpret);
     1.5        return true;
     1.6      }
     1.7 +
     1.8 +    // result is a boolean (0 or 1) and its profile (false_cnt & true_cnt)
     1.9 +    // is a number of each value occurrences.
    1.10 +    Node* result = argument(0);
    1.11 +    if (false_cnt == 0 || true_cnt == 0) {
    1.12 +      // According to profile, one value has been never seen.
    1.13 +      int expected_val = (false_cnt == 0) ? 1 : 0;
    1.14 +
    1.15 +      Node* cmp  = _gvn.transform(new (C) CmpINode(result, intcon(expected_val)));
    1.16 +      Node* test = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq));
    1.17 +
    1.18 +      IfNode* check = create_and_map_if(control(), test, PROB_ALWAYS, COUNT_UNKNOWN);
    1.19 +      Node* fast_path = _gvn.transform(new (C) IfTrueNode(check));
    1.20 +      Node* slow_path = _gvn.transform(new (C) IfFalseNode(check));
    1.21 +
    1.22 +      { // Slow path: uncommon trap for never seen value and then reexecute
    1.23 +        // MethodHandleImpl::profileBoolean() to bump the count, so JIT knows
    1.24 +        // the value has been seen at least once.
    1.25 +        PreserveJVMState pjvms(this);
    1.26 +        PreserveReexecuteState preexecs(this);
    1.27 +        jvms()->set_should_reexecute(true);
    1.28 +
    1.29 +        set_control(slow_path);
    1.30 +        set_i_o(i_o());
    1.31 +
    1.32 +        uncommon_trap_exact(Deoptimization::Reason_intrinsic,
    1.33 +                            Deoptimization::Action_reinterpret);
    1.34 +      }
    1.35 +      // The guard for never seen value enables sharpening of the result and
    1.36 +      // returning a constant. It allows to eliminate branches on the same value
    1.37 +      // later on.
    1.38 +      set_control(fast_path);
    1.39 +      result = intcon(expected_val);
    1.40 +    }
    1.41      // Stop profiling.
    1.42 -    // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode.
    1.43 -    // By replacing method's body with profile data (represented as ProfileBooleanNode
    1.44 +    // MethodHandleImpl::profileBoolean() has profiling logic in its bytecode.
    1.45 +    // By replacing method body with profile data (represented as ProfileBooleanNode
    1.46      // on IR level) we effectively disable profiling.
    1.47      // It enables full speed execution once optimized code is generated.
    1.48 -    Node* profile = _gvn.transform(new (C) ProfileBooleanNode(argument(0), false_cnt, true_cnt));
    1.49 +    Node* profile = _gvn.transform(new (C) ProfileBooleanNode(result, false_cnt, true_cnt));
    1.50      C->record_for_igvn(profile);
    1.51      set_result(profile);
    1.52      return true;

mercurial