提交 258baabe 编写于 作者: V vlivanov

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

Reviewed-by: jrose, kvn
上级 7ec7657b
......@@ -6576,12 +6576,46 @@ bool LibraryCallKit::inline_profileBoolean() {
Deoptimization::Action_reinterpret);
return true;
}
// result is a boolean (0 or 1) and its profile (false_cnt & true_cnt)
// is a number of each value occurrences.
Node* result = argument(0);
if (false_cnt == 0 || true_cnt == 0) {
// According to profile, one value has been never seen.
int expected_val = (false_cnt == 0) ? 1 : 0;
Node* cmp = _gvn.transform(new (C) CmpINode(result, intcon(expected_val)));
Node* test = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq));
IfNode* check = create_and_map_if(control(), test, PROB_ALWAYS, COUNT_UNKNOWN);
Node* fast_path = _gvn.transform(new (C) IfTrueNode(check));
Node* slow_path = _gvn.transform(new (C) IfFalseNode(check));
{ // Slow path: uncommon trap for never seen value and then reexecute
// MethodHandleImpl::profileBoolean() to bump the count, so JIT knows
// the value has been seen at least once.
PreserveJVMState pjvms(this);
PreserveReexecuteState preexecs(this);
jvms()->set_should_reexecute(true);
set_control(slow_path);
set_i_o(i_o());
uncommon_trap_exact(Deoptimization::Reason_intrinsic,
Deoptimization::Action_reinterpret);
}
// The guard for never seen value enables sharpening of the result and
// returning a constant. It allows to eliminate branches on the same value
// later on.
set_control(fast_path);
result = intcon(expected_val);
}
// Stop profiling.
// MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode.
// By replacing method's body with profile data (represented as ProfileBooleanNode
// MethodHandleImpl::profileBoolean() has profiling logic in its bytecode.
// By replacing method body with profile data (represented as ProfileBooleanNode
// on IR level) we effectively disable profiling.
// It enables full speed execution once optimized code is generated.
Node* profile = _gvn.transform(new (C) ProfileBooleanNode(argument(0), false_cnt, true_cnt));
Node* profile = _gvn.transform(new (C) ProfileBooleanNode(result, false_cnt, true_cnt));
C->record_for_igvn(profile);
set_result(profile);
return true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册