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:
parent
68deca9b41
commit
fbd7e788d6
@ -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() {
|
||||
|
@ -52,6 +52,8 @@ class CallFrequency final {
|
||||
return bit_cast<uint32_t>(f.value_);
|
||||
}
|
||||
|
||||
static constexpr float kNoFeedbackCallFrequency = -1;
|
||||
|
||||
private:
|
||||
float value_;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user