[turbofan] Add support for inlining bound functions.

Support inlining across bound functions in the JSCallReducer when we
specialize to the native context. This basically removes all overhead
from bound functions in TurboFan and gives another speed of 10x on my
microbenchmark.

BUG=chromium:535408, chromium:571299, v8:4629
R=jarin@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1581343002

Cr-Commit-Position: refs/heads/master@{#33283}
This commit is contained in:
bmeurer 2016-01-13 23:13:58 -08:00 committed by Commit bot
parent 7440edae1d
commit ae679c5496

View File

@ -260,10 +260,44 @@ Reduction JSCallReducer::ReduceJSCallFunction(Node* node) {
if (*function == function->native_context()->number_function()) {
return ReduceNumberConstructor(node);
}
} else if (m.Value()->IsJSBoundFunction()) {
Handle<JSBoundFunction> function =
Handle<JSBoundFunction>::cast(m.Value());
Handle<JSReceiver> bound_target_function(
function->bound_target_function(), isolate());
Handle<Object> bound_this(function->bound_this(), isolate());
Handle<FixedArray> bound_arguments(function->bound_arguments(),
isolate());
CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
ConvertReceiverMode const convert_mode =
(bound_this->IsNull() || bound_this->IsUndefined())
? ConvertReceiverMode::kNullOrUndefined
: ConvertReceiverMode::kNotNullOrUndefined;
size_t arity = p.arity();
DCHECK_LE(2u, arity);
// Patch {node} to use [[BoundTargetFunction]] and [[BoundThis]].
NodeProperties::ReplaceValueInput(
node, jsgraph()->Constant(bound_target_function), 0);
NodeProperties::ReplaceValueInput(node, jsgraph()->Constant(bound_this),
1);
// Insert the [[BoundArguments]] for {node}.
for (int i = 0; i < bound_arguments->length(); ++i) {
node->InsertInput(
graph()->zone(), i + 2,
jsgraph()->Constant(handle(bound_arguments->get(i), isolate())));
arity++;
}
NodeProperties::ChangeOp(
node, javascript()->CallFunction(arity, p.language_mode(),
CallCountFeedback(p.feedback()),
convert_mode, p.tail_call_mode()));
// Try to further reduce the JSCallFunction {node}.
Reduction const reduction = ReduceJSCallFunction(node);
return reduction.Changed() ? reduction : Changed(node);
}
// Don't mess with other {node}s that have a constant {target}.
// TODO(bmeurer): Also support optimizing bound functions and proxies here.
// TODO(bmeurer): Also support proxies here.
return NoChange();
}