Emit Call node for CallNoFeedback node instead of soft-deopt

Emit call node instead of soft-deopt for CallNoFeedback to
avoid performance penalty incase one-shot code gets optimized.
Tweek the inling heuristic to avoid recurisve inling with stress-opt.

Bug: v8:8106, v8:8072
Change-Id: I09643c0648b6c880f491d08a8a73f1960ca999c0
Reviewed-on: https://chromium-review.googlesource.com/1239075
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Chandan Reddy <chandanreddy@google.com>
Cr-Commit-Position: refs/heads/master@{#56200}
This commit is contained in:
Creddy 2018-09-24 21:39:27 +02:00 committed by Commit Bot
parent 68deca9b41
commit fbd7e788d6
2 changed files with 28 additions and 12 deletions

View File

@ -1791,19 +1791,33 @@ void BytecodeGraphBuilder::VisitCallAnyReceiver() {
}
void BytecodeGraphBuilder::VisitCallNoFeedback() {
PrepareEagerCheckpoint();
// CallNoFeedback is emitted only for one-shot code. Normally the compiler
// will not have to optimize one-shot code. But when the --always-opt or
// --stress-opt flags are set compiler is forced to optimize one-shot code.
// Emiting SoftDeopt to prevent compiler from inlining CallNoFeedback in
// one-shot.
Node* effect = environment()->GetEffectDependency();
Node* control = environment()->GetControlDependency();
DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
bytecode_iterator().current_bytecode()),
ConvertReceiverMode::kAny);
JSTypeHintLowering::LoweringResult deoptimize =
type_hint_lowering().BuildSoftDeopt(effect, control,
DeoptimizeReason::kDeoptimizeNow);
ApplyEarlyReduction(deoptimize);
PrepareEagerCheckpoint();
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
// The receiver is the first register, followed by the arguments in the
// consecutive registers.
int arg_count = static_cast<int>(reg_count) - 1;
// The arity of the Call node -- includes the callee, receiver and function
// arguments.
int arity = 2 + arg_count;
// Setting call frequency to a value less than min_inlining frequency to
// prevent inlining of one-shot call node.
DCHECK(CallFrequency::kNoFeedbackCallFrequency < FLAG_min_inlining_frequency);
const Operator* call = javascript()->Call(
arity, CallFrequency(CallFrequency::kNoFeedbackCallFrequency));
Node* const* call_args = ProcessCallVarArgs(ConvertReceiverMode::kAny, callee,
first_reg, arg_count);
Node* value = ProcessCallArguments(call, call_args, arity);
environment()->BindAccumulator(value, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitCallProperty() {

View File

@ -52,6 +52,8 @@ class CallFrequency final {
return bit_cast<uint32_t>(f.value_);
}
static constexpr float kNoFeedbackCallFrequency = -1;
private:
float value_;
};