Commit 8339b762 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Use the ArgumentsAdaptorTrampoline in case of argument count mismatch.

Call directly into the ArgumentsAdaptorTrampoline when we call a known
JSFunction, but that actual argument count doesn't match the expected
argument count.

R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#31781}
parent 5ee1a75c
......@@ -295,6 +295,13 @@ Callable CodeFactory::CallFunction(Isolate* isolate, int argc,
}
// static
Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(),
ArgumentAdaptorDescriptor(isolate));
}
// static
Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate) {
return Callable(isolate->builtins()->InterpreterPushArgsAndCall(),
......
......@@ -100,6 +100,8 @@ class CodeFactory final {
static Callable CallFunction(Isolate* isolate, int argc,
CallFunctionFlags flags);
static Callable ArgumentAdaptor(Isolate* isolate);
static Callable InterpreterPushArgsAndCall(Isolate* isolate);
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate);
static Callable InterpreterCEntry(Isolate* isolate);
......
......@@ -1589,33 +1589,47 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
Handle<JSFunction> function =
Handle<JSFunction>::cast(target_type->AsConstant()->Value());
Handle<SharedFunctionInfo> shared(function->shared(), isolate());
if (shared->internal_formal_parameter_count() == arity) {
// Grab the context from the {function}.
Node* context =
jsgraph()->Constant(handle(function->context(), isolate()));
NodeProperties::ReplaceContextInput(node, context);
// Check if we need to convert the {receiver}.
if (is_sloppy(shared->language_mode()) && !shared->native() &&
!receiver_type->Is(Type::Receiver())) {
receiver = effect =
graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
receiver, context, frame_state, effect, control);
NodeProperties::ReplaceEffectInput(node, effect);
NodeProperties::ReplaceValueInput(node, receiver, 1);
}
// Remove the eager bailout frame state.
NodeProperties::RemoveFrameStateInput(node, 1);
// Grab the context from the {function}.
Node* context = jsgraph()->Constant(handle(function->context(), isolate()));
NodeProperties::ReplaceContextInput(node, context);
// Check if we need to convert the {receiver}.
if (is_sloppy(shared->language_mode()) && !shared->native() &&
!receiver_type->Is(Type::Receiver())) {
receiver = effect =
graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
receiver, context, frame_state, effect, control);
NodeProperties::ReplaceEffectInput(node, effect);
NodeProperties::ReplaceValueInput(node, receiver, 1);
}
// Remove the eager bailout frame state.
NodeProperties::RemoveFrameStateInput(node, 1);
// Compute flags for the call.
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
if (p.AllowTailCalls()) flags |= CallDescriptor::kSupportsTailCalls;
if (shared->internal_formal_parameter_count() == arity) {
// Patch {node} to a direct call.
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
if (p.AllowTailCalls()) flags |= CallDescriptor::kSupportsTailCalls;
NodeProperties::ChangeOp(node,
common()->Call(Linkage::GetJSCallDescriptor(
graph()->zone(), false, 1 + arity, flags)));
return Changed(node);
} else {
Callable callable = CodeFactory::ArgumentAdaptor(isolate());
node->InsertInput(graph()->zone(), 0,
jsgraph()->HeapConstant(callable.code()));
node->InsertInput(graph()->zone(), 2, jsgraph()->Int32Constant(arity));
node->InsertInput(
graph()->zone(), 3,
jsgraph()->Int32Constant(shared->internal_formal_parameter_count()));
NodeProperties::ChangeOp(
node, common()->Call(Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(),
1 + arity, flags)));
}
return Changed(node);
}
return NoChange();
......
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