Commit 07a711a5 authored by Maya Lekova's avatar Maya Lekova Committed by Commit Bot

[turbofan] Fix wrongly inlined small functions

R=neis@chromium.org,bmeurer@chromium.org

Bug: v8:9002
Change-Id: I778585b8a76561531fd8c6713e48b3a96cf40351
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1528233Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60346}
parent ea9e5a76
...@@ -96,7 +96,7 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { ...@@ -96,7 +96,7 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
return NoChange(); return NoChange();
} }
bool can_inline = false, small_inline = true; bool can_inline = false, force_inline_small = true;
candidate.total_size = 0; candidate.total_size = 0;
Node* frame_state = NodeProperties::GetFrameStateInput(node); Node* frame_state = NodeProperties::GetFrameStateInput(node);
FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op()); FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op());
...@@ -128,8 +128,9 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { ...@@ -128,8 +128,9 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
can_inline = true; can_inline = true;
candidate.total_size += bytecode->length(); candidate.total_size += bytecode->length();
} }
// We don't force inline small functions if any of them is not inlineable
if (!IsSmallInlineFunction(bytecode)) { if (!IsSmallInlineFunction(bytecode)) {
small_inline = false; force_inline_small = false;
} }
} }
if (!can_inline) return NoChange(); if (!can_inline) return NoChange();
...@@ -164,8 +165,8 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { ...@@ -164,8 +165,8 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
} }
// Forcibly inline small functions here. In the case of polymorphic inlining // Forcibly inline small functions here. In the case of polymorphic inlining
// small_inline is set only when all functions are small. // force_inline_small is set only when all functions are small.
if (small_inline && if (force_inline_small &&
cumulative_count_ < FLAG_max_inlined_bytecode_size_absolute) { cumulative_count_ < FLAG_max_inlined_bytecode_size_absolute) {
TRACE("Inlining small function(s) at call site #%d:%s\n", node->id(), TRACE("Inlining small function(s) at call site #%d:%s\n", node->id(),
node->op()->mnemonic()); node->op()->mnemonic());
...@@ -660,15 +661,18 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate, ...@@ -660,15 +661,18 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate,
// Inline the individual, cloned call sites. // Inline the individual, cloned call sites.
for (int i = 0; i < num_calls; ++i) { for (int i = 0; i < num_calls; ++i) {
Node* node = calls[i]; Node* node = calls[i];
if (small_function || if (candidate.can_inline_function[i] &&
(candidate.can_inline_function[i] && (small_function ||
cumulative_count_ < FLAG_max_inlined_bytecode_size_cumulative)) { cumulative_count_ < FLAG_max_inlined_bytecode_size_cumulative)) {
Reduction const reduction = inliner_.ReduceJSCall(node); Reduction const reduction = inliner_.ReduceJSCall(node);
if (reduction.Changed()) { if (reduction.Changed()) {
// Killing the call node is not strictly necessary, but it is safer to // Killing the call node is not strictly necessary, but it is safer to
// make sure we do not resurrect the node. // make sure we do not resurrect the node.
node->Kill(); node->Kill();
cumulative_count_ += candidate.bytecode[i]->length(); // Small functions don't count towards the budget.
if (!small_function) {
cumulative_count_ += candidate.bytecode[i]->length();
}
} }
} }
} }
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --opt --no-always-opt
function f() {
return 42;
}
function g() {
return 52;
}
%NeverOptimizeFunction(f);
function foo(cond) {
let func;
if (cond) {
func = f;
} else {
func = g;
}
func();
}
foo(true);
foo(false);
%OptimizeFunctionOnNextCall(foo);
foo(true);
foo(false);
// Just a sanitary check, we have a DCHECK in js-inlining.cc to make sure
// f is not inlined into foo.
assertUnoptimized(f);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment