Fri, 20 Mar 2015 11:41:34 -0700
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;