Commit e465a4f3 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Support inlining of builtins based on SharedFunctionInfo.

This makes the inlining of the default resolve/reject closures generated
by the Promise constructor effective. To be really useful we still need
to have the Promise constructor inlined (work-in-progress) and eventually
track SharedFunctionInfo feedback in the CALL_IC.

Bug: v8:2206, v8:7253
Change-Id: I08fa8ca72754f459ae36027a55377ef57d411cdc
Reviewed-on: https://chromium-review.googlesource.com/926103
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51390}
parent 46c199a5
...@@ -79,12 +79,15 @@ std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) { ...@@ -79,12 +79,15 @@ std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
} }
namespace { namespace {
Node* CreateBuiltinContinuationFrameStateCommon( Node* CreateBuiltinContinuationFrameStateCommon(
JSGraph* js_graph, Builtins::Name name, Node* context, Node** parameters, JSGraph* jsgraph, FrameStateType frame_type, Builtins::Name name,
int parameter_count, Node* outer_frame_state, Handle<JSFunction> function) { Node* closure, Node* context, Node** parameters, int parameter_count,
Isolate* isolate = js_graph->isolate(); Node* outer_frame_state,
Graph* graph = js_graph->graph(); Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>()) {
CommonOperatorBuilder* common = js_graph->common(); Isolate* const isolate = jsgraph->isolate();
Graph* const graph = jsgraph->graph();
CommonOperatorBuilder* const common = jsgraph->common();
BailoutId bailout_id = Builtins::GetContinuationBailoutId(name); BailoutId bailout_id = Builtins::GetContinuationBailoutId(name);
Callable callable = Builtins::CallableFor(isolate, name); Callable callable = Builtins::CallableFor(isolate, name);
...@@ -93,33 +96,26 @@ Node* CreateBuiltinContinuationFrameStateCommon( ...@@ -93,33 +96,26 @@ Node* CreateBuiltinContinuationFrameStateCommon(
common->StateValues(parameter_count, SparseInputMask::Dense()); common->StateValues(parameter_count, SparseInputMask::Dense());
Node* params_node = graph->NewNode(op_param, parameter_count, parameters); Node* params_node = graph->NewNode(op_param, parameter_count, parameters);
FrameStateType frame_type =
function.is_null() ? FrameStateType::kBuiltinContinuation
: FrameStateType::kJavaScriptBuiltinContinuation;
const FrameStateFunctionInfo* state_info = const FrameStateFunctionInfo* state_info =
common->CreateFrameStateFunctionInfo( common->CreateFrameStateFunctionInfo(frame_type, parameter_count, 0,
frame_type, parameter_count, 0, shared);
function.is_null() ? Handle<SharedFunctionInfo>()
: Handle<SharedFunctionInfo>(function->shared()));
const Operator* op = common->FrameState( const Operator* op = common->FrameState(
bailout_id, OutputFrameStateCombine::Ignore(), state_info); bailout_id, OutputFrameStateCombine::Ignore(), state_info);
Node* function_node = function.is_null() ? js_graph->UndefinedConstant()
: js_graph->HeapConstant(function);
Node* frame_state = graph->NewNode( Node* frame_state = graph->NewNode(
op, params_node, js_graph->EmptyStateValues(), op, params_node, jsgraph->EmptyStateValues(), jsgraph->EmptyStateValues(),
js_graph->EmptyStateValues(), context, function_node, outer_frame_state); context, closure, outer_frame_state);
return frame_state; return frame_state;
} }
} // namespace } // namespace
Node* CreateStubBuiltinContinuationFrameState( Node* CreateStubBuiltinContinuationFrameState(
JSGraph* js_graph, Builtins::Name name, Node* context, JSGraph* jsgraph, Builtins::Name name, Node* context,
Node* const* parameters, int parameter_count, Node* outer_frame_state, Node* const* parameters, int parameter_count, Node* outer_frame_state,
ContinuationFrameStateMode mode) { ContinuationFrameStateMode mode) {
Isolate* isolate = js_graph->isolate(); Isolate* isolate = jsgraph->isolate();
Callable callable = Builtins::CallableFor(isolate, name); Callable callable = Builtins::CallableFor(isolate, name);
CallInterfaceDescriptor descriptor = callable.descriptor(); CallInterfaceDescriptor descriptor = callable.descriptor();
...@@ -140,18 +136,18 @@ Node* CreateStubBuiltinContinuationFrameState( ...@@ -140,18 +136,18 @@ Node* CreateStubBuiltinContinuationFrameState(
} }
return CreateBuiltinContinuationFrameStateCommon( return CreateBuiltinContinuationFrameStateCommon(
js_graph, name, context, actual_parameters.data(), jsgraph, FrameStateType::kBuiltinContinuation, name,
static_cast<int>(actual_parameters.size()), outer_frame_state, jsgraph->UndefinedConstant(), context, actual_parameters.data(),
Handle<JSFunction>()); static_cast<int>(actual_parameters.size()), outer_frame_state);
} }
Node* CreateJavaScriptBuiltinContinuationFrameState( Node* CreateJavaScriptBuiltinContinuationFrameState(
JSGraph* js_graph, Handle<JSFunction> function, Builtins::Name name, JSGraph* jsgraph, Handle<SharedFunctionInfo> shared, Builtins::Name name,
Node* target, Node* context, Node* const* stack_parameters, Node* target, Node* context, Node* const* stack_parameters,
int stack_parameter_count, Node* outer_frame_state, int stack_parameter_count, Node* outer_frame_state,
ContinuationFrameStateMode mode) { ContinuationFrameStateMode mode) {
Isolate* isolate = js_graph->isolate(); Isolate* const isolate = jsgraph->isolate();
Callable callable = Builtins::CallableFor(isolate, name); Callable const callable = Builtins::CallableFor(isolate, name);
// Lazy deopt points where the frame state is assocated with a call get an // Lazy deopt points where the frame state is assocated with a call get an
// additional parameter for the return result from the call that's added by // additional parameter for the return result from the call that's added by
...@@ -163,8 +159,8 @@ Node* CreateJavaScriptBuiltinContinuationFrameState( ...@@ -163,8 +159,8 @@ Node* CreateJavaScriptBuiltinContinuationFrameState(
(mode == ContinuationFrameStateMode::EAGER ? 0 : 1)); (mode == ContinuationFrameStateMode::EAGER ? 0 : 1));
Node* argc = Node* argc =
js_graph->Constant(stack_parameter_count - jsgraph->Constant(stack_parameter_count -
(mode == ContinuationFrameStateMode::EAGER ? 1 : 0)); (mode == ContinuationFrameStateMode::EAGER ? 1 : 0));
// Stack parameters first. They must be first because the receiver is expected // Stack parameters first. They must be first because the receiver is expected
// to be the second value in the translation when creating stack crawls // to be the second value in the translation when creating stack crawls
...@@ -177,12 +173,13 @@ Node* CreateJavaScriptBuiltinContinuationFrameState( ...@@ -177,12 +173,13 @@ Node* CreateJavaScriptBuiltinContinuationFrameState(
// Register parameters follow stack paraemters. The context will be added by // Register parameters follow stack paraemters. The context will be added by
// instruction selector during FrameState translation. // instruction selector during FrameState translation.
actual_parameters.push_back(target); actual_parameters.push_back(target);
actual_parameters.push_back(js_graph->UndefinedConstant()); actual_parameters.push_back(jsgraph->UndefinedConstant());
actual_parameters.push_back(argc); actual_parameters.push_back(argc);
return CreateBuiltinContinuationFrameStateCommon( return CreateBuiltinContinuationFrameStateCommon(
js_graph, name, context, &actual_parameters[0], jsgraph, FrameStateType::kJavaScriptBuiltinContinuation, name, target,
static_cast<int>(actual_parameters.size()), outer_frame_state, function); context, &actual_parameters[0],
static_cast<int>(actual_parameters.size()), outer_frame_state, shared);
} }
} // namespace compiler } // namespace compiler
......
...@@ -151,7 +151,7 @@ Node* CreateStubBuiltinContinuationFrameState( ...@@ -151,7 +151,7 @@ Node* CreateStubBuiltinContinuationFrameState(
ContinuationFrameStateMode mode); ContinuationFrameStateMode mode);
Node* CreateJavaScriptBuiltinContinuationFrameState( Node* CreateJavaScriptBuiltinContinuationFrameState(
JSGraph* graph, Handle<JSFunction> function, Builtins::Name name, JSGraph* graph, Handle<SharedFunctionInfo> shared, Builtins::Name name,
Node* target, Node* context, Node* const* stack_parameters, Node* target, Node* context, Node* const* stack_parameters,
int stack_parameter_count, Node* outer_frame_state, int stack_parameter_count, Node* outer_frame_state,
ContinuationFrameStateMode mode); ContinuationFrameStateMode mode);
......
...@@ -339,12 +339,25 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) { ...@@ -339,12 +339,25 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) {
Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) { Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
Handle<JSFunction> call = Handle<JSFunction>::cast( Node* target = NodeProperties::GetValueInput(node, 0);
HeapObjectMatcher(NodeProperties::GetValueInput(node, 0)).Value()); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Change context of {node} to the Function.prototype.call context, // Change context of {node} to the Function.prototype.call context,
// to ensure any exception is thrown in the correct context. // to ensure any exception is thrown in the correct context.
NodeProperties::ReplaceContextInput( Node* context;
node, jsgraph()->HeapConstant(handle(call->context(), isolate()))); HeapObjectMatcher m(target);
if (m.HasValue()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
context = jsgraph()->HeapConstant(handle(function->context(), isolate()));
} else {
context = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target,
effect, control);
}
NodeProperties::ReplaceContextInput(node, context);
NodeProperties::ReplaceEffectInput(node, effect);
// Remove the target from {node} and use the receiver as target instead, and // Remove the target from {node} and use the receiver as target instead, and
// the thisArg becomes the new target. If thisArg was not provided, insert // the thisArg becomes the new target. If thisArg was not provided, insert
// undefined instead. // undefined instead.
...@@ -811,8 +824,8 @@ void JSCallReducer::WireInLoopEnd(Node* loop, Node* eloop, Node* vloop, Node* k, ...@@ -811,8 +824,8 @@ void JSCallReducer::WireInLoopEnd(Node* loop, Node* eloop, Node* vloop, Node* k,
eloop->ReplaceInput(1, effect); eloop->ReplaceInput(1, effect);
} }
Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, Reduction JSCallReducer::ReduceArrayForEach(Node* node,
Node* node) { Handle<SharedFunctionInfo> shared) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -885,7 +898,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, ...@@ -885,7 +898,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
// Check whether the given callback function is callable. Note that this has // Check whether the given callback function is callable. Note that this has
// to happen outside the loop to make sure we also throw on empty arrays. // to happen outside the loop to make sure we also throw on empty arrays.
Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayForEachLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayForEachLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
Node* check_fail = nullptr; Node* check_fail = nullptr;
...@@ -908,7 +921,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, ...@@ -908,7 +921,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
control = if_true; control = if_true;
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayForEachLoopEagerDeoptContinuation, jsgraph(), shared, Builtins::kArrayForEachLoopEagerDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::EAGER); outer_frame_state, ContinuationFrameStateMode::EAGER);
...@@ -956,7 +969,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, ...@@ -956,7 +969,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
} }
frame_state = CreateJavaScriptBuiltinContinuationFrameState( frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayForEachLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayForEachLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
...@@ -999,16 +1012,16 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, ...@@ -999,16 +1012,16 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
return Replace(jsgraph()->UndefinedConstant()); return Replace(jsgraph()->UndefinedConstant());
} }
Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, Reduction JSCallReducer::ReduceArrayReduce(Node* node,
Node* node, ArrayReduceDirection direction,
ArrayReduceDirection direction) { Handle<SharedFunctionInfo> shared) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) { if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
return NoChange(); return NoChange();
} }
bool left = direction == ArrayReduceDirection::kArrayReduceLeft; bool left = direction == ArrayReduceDirection::kLeft;
Node* outer_frame_state = NodeProperties::GetFrameStateInput(node); Node* outer_frame_state = NodeProperties::GetFrameStateInput(node);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
...@@ -1076,7 +1089,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1076,7 +1089,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
jsgraph()->UndefinedConstant()}); jsgraph()->UndefinedConstant()});
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin_lazy, node->InputAt(0), context, jsgraph(), shared, builtin_lazy, node->InputAt(0), context,
checkpoint_params.data(), stack_parameters - 1, outer_frame_state, checkpoint_params.data(), stack_parameters - 1, outer_frame_state,
ContinuationFrameStateMode::LAZY); ContinuationFrameStateMode::LAZY);
} }
...@@ -1104,7 +1117,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1104,7 +1117,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* find_first_element_frame_state = Node* find_first_element_frame_state =
CreateJavaScriptBuiltinContinuationFrameState( CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin_eager, node->InputAt(0), context, jsgraph(), shared, builtin_eager, node->InputAt(0), context,
checkpoint_params.data(), stack_parameters, outer_frame_state, checkpoint_params.data(), stack_parameters, outer_frame_state,
ContinuationFrameStateMode::EAGER); ContinuationFrameStateMode::EAGER);
...@@ -1173,7 +1186,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1173,7 +1186,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
{receiver, fncallback, k, original_length, curloop}); {receiver, fncallback, k, original_length, curloop});
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin_eager, node->InputAt(0), context, jsgraph(), shared, builtin_eager, node->InputAt(0), context,
checkpoint_params.data(), stack_parameters, outer_frame_state, checkpoint_params.data(), stack_parameters, outer_frame_state,
ContinuationFrameStateMode::EAGER); ContinuationFrameStateMode::EAGER);
effect = effect =
...@@ -1219,7 +1232,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1219,7 +1232,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
{receiver, fncallback, next_k, original_length, curloop}); {receiver, fncallback, next_k, original_length, curloop});
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, builtin_lazy, node->InputAt(0), context, jsgraph(), shared, builtin_lazy, node->InputAt(0), context,
checkpoint_params.data(), stack_parameters - 1, outer_frame_state, checkpoint_params.data(), stack_parameters - 1, outer_frame_state,
ContinuationFrameStateMode::LAZY); ContinuationFrameStateMode::LAZY);
...@@ -1273,8 +1286,8 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function, ...@@ -1273,8 +1286,8 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
return Replace(curloop); return Replace(curloop);
} }
Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function, Reduction JSCallReducer::ReduceArrayMap(Node* node,
Node* node) { Handle<SharedFunctionInfo> shared) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -1350,7 +1363,7 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function, ...@@ -1350,7 +1363,7 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function,
// Check whether the given callback function is callable. Note that this has // Check whether the given callback function is callable. Note that this has
// to happen outside the loop to make sure we also throw on empty arrays. // to happen outside the loop to make sure we also throw on empty arrays.
Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayMapLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayMapLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
Node* check_fail = nullptr; Node* check_fail = nullptr;
...@@ -1373,7 +1386,7 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function, ...@@ -1373,7 +1386,7 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function,
control = if_true; control = if_true;
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayMapLoopEagerDeoptContinuation, jsgraph(), shared, Builtins::kArrayMapLoopEagerDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::EAGER); outer_frame_state, ContinuationFrameStateMode::EAGER);
...@@ -1422,7 +1435,7 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function, ...@@ -1422,7 +1435,7 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function,
// This frame state is dealt with by hand in // This frame state is dealt with by hand in
// ArrayMapLoopLazyDeoptContinuation. // ArrayMapLoopLazyDeoptContinuation.
frame_state = CreateJavaScriptBuiltinContinuationFrameState( frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayMapLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayMapLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
...@@ -1474,8 +1487,8 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function, ...@@ -1474,8 +1487,8 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function,
return Replace(a); return Replace(a);
} }
Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function, Reduction JSCallReducer::ReduceArrayFilter(Node* node,
Node* node) { Handle<SharedFunctionInfo> shared) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -1569,7 +1582,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function, ...@@ -1569,7 +1582,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayFilterLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayFilterLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
WireInCallbackIsCallableCheck(fncallback, context, check_frame_state, WireInCallbackIsCallableCheck(fncallback, context, check_frame_state,
...@@ -1597,7 +1610,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function, ...@@ -1597,7 +1610,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayFilterLoopEagerDeoptContinuation, jsgraph(), shared, Builtins::kArrayFilterLoopEagerDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::EAGER); outer_frame_state, ContinuationFrameStateMode::EAGER);
...@@ -1654,7 +1667,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function, ...@@ -1654,7 +1667,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayFilterLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayFilterLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
...@@ -1683,7 +1696,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function, ...@@ -1683,7 +1696,7 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function,
callback_value}); callback_value});
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayFilterLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayFilterLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::EAGER); outer_frame_state, ContinuationFrameStateMode::EAGER);
...@@ -1729,9 +1742,8 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function, ...@@ -1729,9 +1742,8 @@ Reduction JSCallReducer::ReduceArrayFilter(Handle<JSFunction> function,
return Replace(a); return Replace(a);
} }
Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant, Reduction JSCallReducer::ReduceArrayFind(Node* node, ArrayFindVariant variant,
Handle<JSFunction> function, Handle<SharedFunctionInfo> shared) {
Node* node) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -1817,8 +1829,8 @@ Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant, ...@@ -1817,8 +1829,8 @@ Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant,
Node* check_throw = nullptr; Node* check_throw = nullptr;
{ {
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, lazy_continuation_builtin, node->InputAt(0), jsgraph(), shared, lazy_continuation_builtin, node->InputAt(0), context,
context, &checkpoint_params[0], stack_parameters, outer_frame_state, &checkpoint_params[0], stack_parameters, outer_frame_state,
ContinuationFrameStateMode::LAZY); ContinuationFrameStateMode::LAZY);
WireInCallbackIsCallableCheck(fncallback, context, frame_state, effect, WireInCallbackIsCallableCheck(fncallback, context, frame_state, effect,
&control, &check_fail, &check_throw); &control, &check_fail, &check_throw);
...@@ -1843,7 +1855,7 @@ Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant, ...@@ -1843,7 +1855,7 @@ Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant,
// Check the map hasn't changed during the iteration. // Check the map hasn't changed during the iteration.
{ {
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, eager_continuation_builtin, node->InputAt(0), jsgraph(), shared, eager_continuation_builtin, node->InputAt(0),
context, &checkpoint_params[0], stack_parameters, outer_frame_state, context, &checkpoint_params[0], stack_parameters, outer_frame_state,
ContinuationFrameStateMode::EAGER); ContinuationFrameStateMode::EAGER);
...@@ -1886,7 +1898,7 @@ Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant, ...@@ -1886,7 +1898,7 @@ Reduction JSCallReducer::ReduceArrayFind(ArrayFindVariant variant,
static_cast<int>(call_checkpoint_params.size()); static_cast<int>(call_checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, after_callback_lazy_continuation_builtin, jsgraph(), shared, after_callback_lazy_continuation_builtin,
node->InputAt(0), context, &call_checkpoint_params[0], node->InputAt(0), context, &call_checkpoint_params[0],
call_stack_parameters, outer_frame_state, call_stack_parameters, outer_frame_state,
ContinuationFrameStateMode::LAZY); ContinuationFrameStateMode::LAZY);
...@@ -2067,8 +2079,8 @@ Node* JSCallReducer::SafeLoadElement(ElementsKind kind, Node* receiver, ...@@ -2067,8 +2079,8 @@ Node* JSCallReducer::SafeLoadElement(ElementsKind kind, Node* receiver,
return element; return element;
} }
Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function, Reduction JSCallReducer::ReduceArrayEvery(Node* node,
Node* node) { Handle<SharedFunctionInfo> shared) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -2139,7 +2151,7 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function, ...@@ -2139,7 +2151,7 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayEveryLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayEveryLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
WireInCallbackIsCallableCheck(fncallback, context, check_frame_state, WireInCallbackIsCallableCheck(fncallback, context, check_frame_state,
...@@ -2165,7 +2177,7 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function, ...@@ -2165,7 +2177,7 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayEveryLoopEagerDeoptContinuation, jsgraph(), shared, Builtins::kArrayEveryLoopEagerDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::EAGER); outer_frame_state, ContinuationFrameStateMode::EAGER);
...@@ -2221,7 +2233,7 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function, ...@@ -2221,7 +2233,7 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArrayEveryLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArrayEveryLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
...@@ -2287,8 +2299,8 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function, ...@@ -2287,8 +2299,8 @@ Reduction JSCallReducer::ReduceArrayEvery(Handle<JSFunction> function,
return Replace(return_value); return Replace(return_value);
} }
Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function, Reduction JSCallReducer::ReduceArraySome(Node* node,
Node* node) { Handle<SharedFunctionInfo> shared) {
if (!FLAG_turbo_inline_array_builtins) return NoChange(); if (!FLAG_turbo_inline_array_builtins) return NoChange();
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
...@@ -2361,7 +2373,7 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function, ...@@ -2361,7 +2373,7 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* check_frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArraySomeLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArraySomeLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
WireInCallbackIsCallableCheck(fncallback, context, check_frame_state, WireInCallbackIsCallableCheck(fncallback, context, check_frame_state,
...@@ -2392,7 +2404,7 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function, ...@@ -2392,7 +2404,7 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArraySomeLoopEagerDeoptContinuation, jsgraph(), shared, Builtins::kArraySomeLoopEagerDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::EAGER); outer_frame_state, ContinuationFrameStateMode::EAGER);
...@@ -2448,7 +2460,7 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function, ...@@ -2448,7 +2460,7 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function,
const int stack_parameters = static_cast<int>(checkpoint_params.size()); const int stack_parameters = static_cast<int>(checkpoint_params.size());
Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState( Node* frame_state = CreateJavaScriptBuiltinContinuationFrameState(
jsgraph(), function, Builtins::kArraySomeLoopLazyDeoptContinuation, jsgraph(), shared, Builtins::kArraySomeLoopLazyDeoptContinuation,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters, node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY); outer_frame_state, ContinuationFrameStateMode::LAZY);
...@@ -2516,19 +2528,20 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function, ...@@ -2516,19 +2528,20 @@ Reduction JSCallReducer::ReduceArraySome(Handle<JSFunction> function,
return Replace(return_value); return Replace(return_value);
} }
Reduction JSCallReducer::ReduceCallApiFunction(Node* node, Reduction JSCallReducer::ReduceCallApiFunction(
Handle<JSFunction> function) { Node* node, Handle<SharedFunctionInfo> shared) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
int const argc = static_cast<int>(p.arity()) - 2; int const argc = static_cast<int>(p.arity()) - 2;
Node* target = NodeProperties::GetValueInput(node, 0);
Node* receiver = (p.convert_mode() == ConvertReceiverMode::kNullOrUndefined) Node* receiver = (p.convert_mode() == ConvertReceiverMode::kNullOrUndefined)
? jsgraph()->HeapConstant(global_proxy()) ? jsgraph()->HeapConstant(global_proxy())
: NodeProperties::GetValueInput(node, 1); : NodeProperties::GetValueInput(node, 1);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Handle<FunctionTemplateInfo> function_template_info( Handle<FunctionTemplateInfo> function_template_info(
FunctionTemplateInfo::cast(function->shared()->function_data())); FunctionTemplateInfo::cast(shared->function_data()));
Handle<Context> context(function->context());
// CallApiCallbackStub expects the target in a register, so we count it out, // CallApiCallbackStub expects the target in a register, so we count it out,
// and counts the receiver as an implicit argument, so we count the receiver // and counts the receiver as an implicit argument, so we count the receiver
...@@ -2577,6 +2590,11 @@ Reduction JSCallReducer::ReduceCallApiFunction(Node* node, ...@@ -2577,6 +2590,11 @@ Reduction JSCallReducer::ReduceCallApiFunction(Node* node,
} }
} }
// Load the {target}s context.
Node* context = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target,
effect, control);
// CallApiCallbackStub's register arguments: code, target, call data, holder, // CallApiCallbackStub's register arguments: code, target, call data, holder,
// function address. // function address.
// TODO(turbofan): Consider introducing a JSCallApiCallback operator for // TODO(turbofan): Consider introducing a JSCallApiCallback operator for
...@@ -2600,14 +2618,14 @@ Reduction JSCallReducer::ReduceCallApiFunction(Node* node, ...@@ -2600,14 +2618,14 @@ Reduction JSCallReducer::ReduceCallApiFunction(Node* node,
&api_function, ExternalReference::DIRECT_API_CALL, isolate()); &api_function, ExternalReference::DIRECT_API_CALL, isolate());
node->InsertInput(graph()->zone(), 0, node->InsertInput(graph()->zone(), 0,
jsgraph()->HeapConstant(stub.GetCode())); jsgraph()->HeapConstant(stub.GetCode()));
node->ReplaceInput(1, jsgraph()->Constant(context)); node->ReplaceInput(1, context);
node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(data)); node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(data));
node->InsertInput(graph()->zone(), 3, holder); node->InsertInput(graph()->zone(), 3, holder);
node->InsertInput(graph()->zone(), 4, node->InsertInput(graph()->zone(), 4,
jsgraph()->ExternalConstant(function_reference)); jsgraph()->ExternalConstant(function_reference));
node->ReplaceInput(5, receiver); node->ReplaceInput(5, receiver);
// Remove context input. node->RemoveInput(6 + argc); // Remove context input.
node->RemoveInput(6 + argc); node->ReplaceInput(7 + argc, effect); // Update effect input.
NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
return Changed(node); return Changed(node);
} }
...@@ -2885,127 +2903,11 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -2885,127 +2903,11 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
if (m.HasValue()) { if (m.HasValue()) {
if (m.Value()->IsJSFunction()) { if (m.Value()->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
Handle<SharedFunctionInfo> shared(function->shared(), isolate());
// Do not reduce calls to functions with break points.
if (shared->HasBreakInfo()) return NoChange();
// Raise a TypeError if the {target} is a "classConstructor".
if (IsClassConstructor(shared->kind())) {
NodeProperties::ReplaceValueInputs(node, target);
NodeProperties::ChangeOp(
node, javascript()->CallRuntime(
Runtime::kThrowConstructorNonCallableError, 1));
return Changed(node);
}
// Don't inline cross native context. // Don't inline cross native context.
if (function->native_context() != *native_context()) return NoChange(); if (function->native_context() != *native_context()) return NoChange();
// Check for known builtin functions. return ReduceJSCall(node, handle(function->shared(), isolate()));
switch (shared->code()->builtin_index()) {
case Builtins::kArrayConstructor:
return ReduceArrayConstructor(node);
case Builtins::kBooleanConstructor:
return ReduceBooleanConstructor(node);
case Builtins::kFunctionPrototypeApply:
return ReduceFunctionPrototypeApply(node);
case Builtins::kFastFunctionPrototypeBind:
return ReduceFunctionPrototypeBind(node);
case Builtins::kFunctionPrototypeCall:
return ReduceFunctionPrototypeCall(node);
case Builtins::kFunctionPrototypeHasInstance:
return ReduceFunctionPrototypeHasInstance(node);
case Builtins::kObjectConstructor:
return ReduceObjectConstructor(node);
case Builtins::kObjectGetPrototypeOf:
return ReduceObjectGetPrototypeOf(node);
case Builtins::kObjectIs:
return ReduceObjectIs(node);
case Builtins::kObjectPrototypeGetProto:
return ReduceObjectPrototypeGetProto(node);
case Builtins::kObjectPrototypeHasOwnProperty:
return ReduceObjectPrototypeHasOwnProperty(node);
case Builtins::kObjectPrototypeIsPrototypeOf:
return ReduceObjectPrototypeIsPrototypeOf(node);
case Builtins::kReflectApply:
return ReduceReflectApply(node);
case Builtins::kReflectConstruct:
return ReduceReflectConstruct(node);
case Builtins::kReflectGet:
return ReduceReflectGet(node);
case Builtins::kReflectGetPrototypeOf:
return ReduceReflectGetPrototypeOf(node);
case Builtins::kReflectHas:
return ReduceReflectHas(node);
case Builtins::kArrayForEach:
return ReduceArrayForEach(function, node);
case Builtins::kArrayMap:
return ReduceArrayMap(function, node);
case Builtins::kArrayFilter:
return ReduceArrayFilter(function, node);
case Builtins::kArrayReduce:
return ReduceArrayReduce(function, node,
ArrayReduceDirection::kArrayReduceLeft);
case Builtins::kArrayReduceRight:
return ReduceArrayReduce(function, node,
ArrayReduceDirection::kArrayReduceRight);
case Builtins::kArrayPrototypeFind:
return ReduceArrayFind(ArrayFindVariant::kFind, function, node);
case Builtins::kArrayPrototypeFindIndex:
return ReduceArrayFind(ArrayFindVariant::kFindIndex, function, node);
case Builtins::kArrayEvery:
return ReduceArrayEvery(function, node);
case Builtins::kArraySome:
return ReduceArraySome(function, node);
case Builtins::kArrayPrototypePush:
return ReduceArrayPrototypePush(node);
case Builtins::kArrayPrototypePop:
return ReduceArrayPrototypePop(node);
case Builtins::kArrayPrototypeShift:
return ReduceArrayPrototypeShift(node);
case Builtins::kReturnReceiver:
return ReduceReturnReceiver(node);
case Builtins::kStringPrototypeIndexOf:
return ReduceStringPrototypeIndexOf(function, node);
case Builtins::kStringPrototypeCharAt:
return ReduceStringPrototypeStringAt(simplified()->StringCharAt(),
node);
case Builtins::kStringPrototypeCharCodeAt:
return ReduceStringPrototypeStringAt(simplified()->StringCharCodeAt(),
node);
case Builtins::kStringPrototypeCodePointAt:
return ReduceStringPrototypeStringAt(
simplified()->StringCodePointAt(UnicodeEncoding::UTF32), node);
case Builtins::kAsyncFunctionPromiseCreate:
return ReduceAsyncFunctionPromiseCreate(node);
case Builtins::kAsyncFunctionPromiseRelease:
return ReduceAsyncFunctionPromiseRelease(node);
case Builtins::kPromiseCapabilityDefaultReject:
return ReducePromiseCapabilityDefaultReject(node);
case Builtins::kPromiseCapabilityDefaultResolve:
return ReducePromiseCapabilityDefaultResolve(node);
case Builtins::kPromiseInternalConstructor:
return ReducePromiseInternalConstructor(node);
case Builtins::kPromiseInternalReject:
return ReducePromiseInternalReject(node);
case Builtins::kPromiseInternalResolve:
return ReducePromiseInternalResolve(node);
case Builtins::kPromisePrototypeCatch:
return ReducePromisePrototypeCatch(node);
case Builtins::kPromisePrototypeFinally:
return ReducePromisePrototypeFinally(node);
case Builtins::kPromisePrototypeThen:
return ReducePromisePrototypeThen(node);
case Builtins::kPromiseResolveTrampoline:
return ReducePromiseResolveTrampoline(node);
default:
break;
}
if (!FLAG_runtime_stats && shared->IsApiFunction()) {
return ReduceCallApiFunction(node, function);
}
} else if (m.Value()->IsJSBoundFunction()) { } else if (m.Value()->IsJSBoundFunction()) {
Handle<JSBoundFunction> function = Handle<JSBoundFunction> function =
Handle<JSBoundFunction>::cast(m.Value()); Handle<JSBoundFunction>::cast(m.Value());
...@@ -3043,6 +2945,15 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -3043,6 +2945,15 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
return NoChange(); return NoChange();
} }
// If {target} is the result of a JSCreateClosure operation, we can
// just immediately try to inline based on the SharedFunctionInfo,
// since TurboFan generally doesn't inline cross-context, and hence
// the {target} must have the same native context as the call site.
if (target->opcode() == IrOpcode::kJSCreateClosure) {
CreateClosureParameters const& p = CreateClosureParametersOf(target->op());
return ReduceJSCall(node, p.shared_info());
}
// If {target} is the result of a JSCreateBoundFunction operation, // If {target} is the result of a JSCreateBoundFunction operation,
// we can just fold the construction and call the bound target // we can just fold the construction and call the bound target
// function directly instead. // function directly instead.
...@@ -3118,6 +3029,125 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -3118,6 +3029,125 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
return NoChange(); return NoChange();
} }
Reduction JSCallReducer::ReduceJSCall(Node* node,
Handle<SharedFunctionInfo> shared) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
Node* target = NodeProperties::GetValueInput(node, 0);
// Do not reduce calls to functions with break points.
if (shared->HasBreakInfo()) return NoChange();
// Raise a TypeError if the {target} is a "classConstructor".
if (IsClassConstructor(shared->kind())) {
NodeProperties::ReplaceValueInputs(node, target);
NodeProperties::ChangeOp(
node, javascript()->CallRuntime(
Runtime::kThrowConstructorNonCallableError, 1));
return Changed(node);
}
// Check for known builtin functions.
switch (shared->code()->builtin_index()) {
case Builtins::kArrayConstructor:
return ReduceArrayConstructor(node);
case Builtins::kBooleanConstructor:
return ReduceBooleanConstructor(node);
case Builtins::kFunctionPrototypeApply:
return ReduceFunctionPrototypeApply(node);
case Builtins::kFastFunctionPrototypeBind:
return ReduceFunctionPrototypeBind(node);
case Builtins::kFunctionPrototypeCall:
return ReduceFunctionPrototypeCall(node);
case Builtins::kFunctionPrototypeHasInstance:
return ReduceFunctionPrototypeHasInstance(node);
case Builtins::kObjectConstructor:
return ReduceObjectConstructor(node);
case Builtins::kObjectGetPrototypeOf:
return ReduceObjectGetPrototypeOf(node);
case Builtins::kObjectIs:
return ReduceObjectIs(node);
case Builtins::kObjectPrototypeGetProto:
return ReduceObjectPrototypeGetProto(node);
case Builtins::kObjectPrototypeHasOwnProperty:
return ReduceObjectPrototypeHasOwnProperty(node);
case Builtins::kObjectPrototypeIsPrototypeOf:
return ReduceObjectPrototypeIsPrototypeOf(node);
case Builtins::kReflectApply:
return ReduceReflectApply(node);
case Builtins::kReflectConstruct:
return ReduceReflectConstruct(node);
case Builtins::kReflectGet:
return ReduceReflectGet(node);
case Builtins::kReflectGetPrototypeOf:
return ReduceReflectGetPrototypeOf(node);
case Builtins::kReflectHas:
return ReduceReflectHas(node);
case Builtins::kArrayForEach:
return ReduceArrayForEach(node, shared);
case Builtins::kArrayMap:
return ReduceArrayMap(node, shared);
case Builtins::kArrayFilter:
return ReduceArrayFilter(node, shared);
case Builtins::kArrayReduce:
return ReduceArrayReduce(node, ArrayReduceDirection::kLeft, shared);
case Builtins::kArrayReduceRight:
return ReduceArrayReduce(node, ArrayReduceDirection::kRight, shared);
case Builtins::kArrayPrototypeFind:
return ReduceArrayFind(node, ArrayFindVariant::kFind, shared);
case Builtins::kArrayPrototypeFindIndex:
return ReduceArrayFind(node, ArrayFindVariant::kFindIndex, shared);
case Builtins::kArrayEvery:
return ReduceArrayEvery(node, shared);
case Builtins::kArraySome:
return ReduceArraySome(node, shared);
case Builtins::kArrayPrototypePush:
return ReduceArrayPrototypePush(node);
case Builtins::kArrayPrototypePop:
return ReduceArrayPrototypePop(node);
case Builtins::kArrayPrototypeShift:
return ReduceArrayPrototypeShift(node);
case Builtins::kReturnReceiver:
return ReduceReturnReceiver(node);
case Builtins::kStringPrototypeIndexOf:
return ReduceStringPrototypeIndexOf(node);
case Builtins::kStringPrototypeCharAt:
return ReduceStringPrototypeStringAt(simplified()->StringCharAt(), node);
case Builtins::kStringPrototypeCharCodeAt:
return ReduceStringPrototypeStringAt(simplified()->StringCharCodeAt(),
node);
case Builtins::kStringPrototypeCodePointAt:
return ReduceStringPrototypeStringAt(
simplified()->StringCodePointAt(UnicodeEncoding::UTF32), node);
case Builtins::kAsyncFunctionPromiseCreate:
return ReduceAsyncFunctionPromiseCreate(node);
case Builtins::kAsyncFunctionPromiseRelease:
return ReduceAsyncFunctionPromiseRelease(node);
case Builtins::kPromiseCapabilityDefaultReject:
return ReducePromiseCapabilityDefaultReject(node);
case Builtins::kPromiseCapabilityDefaultResolve:
return ReducePromiseCapabilityDefaultResolve(node);
case Builtins::kPromiseInternalConstructor:
return ReducePromiseInternalConstructor(node);
case Builtins::kPromiseInternalReject:
return ReducePromiseInternalReject(node);
case Builtins::kPromiseInternalResolve:
return ReducePromiseInternalResolve(node);
case Builtins::kPromisePrototypeCatch:
return ReducePromisePrototypeCatch(node);
case Builtins::kPromisePrototypeFinally:
return ReducePromisePrototypeFinally(node);
case Builtins::kPromisePrototypeThen:
return ReducePromisePrototypeThen(node);
default:
break;
}
if (!FLAG_runtime_stats && shared->IsApiFunction()) {
return ReduceCallApiFunction(node, shared);
}
return NoChange();
}
Reduction JSCallReducer::ReduceJSCallWithArrayLike(Node* node) { Reduction JSCallReducer::ReduceJSCallWithArrayLike(Node* node) {
DCHECK_EQ(IrOpcode::kJSCallWithArrayLike, node->opcode()); DCHECK_EQ(IrOpcode::kJSCallWithArrayLike, node->opcode());
CallFrequency frequency = CallFrequencyOf(node->op()); CallFrequency frequency = CallFrequencyOf(node->op());
...@@ -3360,8 +3390,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -3360,8 +3390,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
// ES6 String.prototype.indexOf(searchString [, position]) // ES6 String.prototype.indexOf(searchString [, position])
// #sec-string.prototype.indexof // #sec-string.prototype.indexof
Reduction JSCallReducer::ReduceStringPrototypeIndexOf( Reduction JSCallReducer::ReduceStringPrototypeIndexOf(Node* node) {
Handle<JSFunction> function, Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op()); CallParameters const& p = CallParametersOf(node->op());
if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) { if (p.speculation_mode() == SpeculationMode::kDisallowSpeculation) {
......
...@@ -52,10 +52,10 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -52,10 +52,10 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
void Finalize() final; void Finalize() final;
private: private:
enum ArrayReduceDirection { kArrayReduceLeft, kArrayReduceRight };
Reduction ReduceArrayConstructor(Node* node); Reduction ReduceArrayConstructor(Node* node);
Reduction ReduceBooleanConstructor(Node* node); Reduction ReduceBooleanConstructor(Node* node);
Reduction ReduceCallApiFunction(Node* node, Handle<JSFunction> function); Reduction ReduceCallApiFunction(Node* node,
Handle<SharedFunctionInfo> shared);
Reduction ReduceFunctionPrototypeApply(Node* node); Reduction ReduceFunctionPrototypeApply(Node* node);
Reduction ReduceFunctionPrototypeBind(Node* node); Reduction ReduceFunctionPrototypeBind(Node* node);
Reduction ReduceFunctionPrototypeCall(Node* node); Reduction ReduceFunctionPrototypeCall(Node* node);
...@@ -72,16 +72,17 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -72,16 +72,17 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Reduction ReduceReflectGet(Node* node); Reduction ReduceReflectGet(Node* node);
Reduction ReduceReflectGetPrototypeOf(Node* node); Reduction ReduceReflectGetPrototypeOf(Node* node);
Reduction ReduceReflectHas(Node* node); Reduction ReduceReflectHas(Node* node);
Reduction ReduceArrayForEach(Handle<JSFunction> function, Node* node); Reduction ReduceArrayForEach(Node* node, Handle<SharedFunctionInfo> shared);
Reduction ReduceArrayReduce(Handle<JSFunction> function, Node* node, enum class ArrayReduceDirection { kLeft, kRight };
ArrayReduceDirection direction); Reduction ReduceArrayReduce(Node* node, ArrayReduceDirection direction,
Reduction ReduceArrayMap(Handle<JSFunction> function, Node* node); Handle<SharedFunctionInfo> shared);
Reduction ReduceArrayFilter(Handle<JSFunction> function, Node* node); Reduction ReduceArrayMap(Node* node, Handle<SharedFunctionInfo> shared);
enum class ArrayFindVariant : uint8_t { kFind, kFindIndex }; Reduction ReduceArrayFilter(Node* node, Handle<SharedFunctionInfo> shared);
Reduction ReduceArrayFind(ArrayFindVariant variant, enum class ArrayFindVariant { kFind, kFindIndex };
Handle<JSFunction> function, Node* node); Reduction ReduceArrayFind(Node* node, ArrayFindVariant variant,
Reduction ReduceArrayEvery(Handle<JSFunction> function, Node* node); Handle<SharedFunctionInfo> shared);
Reduction ReduceArraySome(Handle<JSFunction> function, Node* node); Reduction ReduceArrayEvery(Node* node, Handle<SharedFunctionInfo> shared);
Reduction ReduceArraySome(Node* node, Handle<SharedFunctionInfo> shared);
Reduction ReduceArrayPrototypePush(Node* node); Reduction ReduceArrayPrototypePush(Node* node);
Reduction ReduceArrayPrototypePop(Node* node); Reduction ReduceArrayPrototypePop(Node* node);
Reduction ReduceArrayPrototypeShift(Node* node); Reduction ReduceArrayPrototypeShift(Node* node);
...@@ -92,11 +93,11 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -92,11 +93,11 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Reduction ReduceJSConstructWithArrayLike(Node* node); Reduction ReduceJSConstructWithArrayLike(Node* node);
Reduction ReduceJSConstructWithSpread(Node* node); Reduction ReduceJSConstructWithSpread(Node* node);
Reduction ReduceJSCall(Node* node); Reduction ReduceJSCall(Node* node);
Reduction ReduceJSCall(Node* node, Handle<SharedFunctionInfo> shared);
Reduction ReduceJSCallWithArrayLike(Node* node); Reduction ReduceJSCallWithArrayLike(Node* node);
Reduction ReduceJSCallWithSpread(Node* node); Reduction ReduceJSCallWithSpread(Node* node);
Reduction ReduceReturnReceiver(Node* node); Reduction ReduceReturnReceiver(Node* node);
Reduction ReduceStringPrototypeIndexOf(Handle<JSFunction> function, Reduction ReduceStringPrototypeIndexOf(Node* node);
Node* node);
Reduction ReduceStringPrototypeStringAt( Reduction ReduceStringPrototypeStringAt(
const Operator* string_access_operator, Node* node); const Operator* string_access_operator, Node* node);
Reduction ReduceAsyncFunctionPromiseCreate(Node* node); Reduction ReduceAsyncFunctionPromiseCreate(Node* node);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --opt // Flags: --allow-natives-syntax
(function() { (function() {
var resolve, value; var resolve, value;
...@@ -25,3 +25,23 @@ ...@@ -25,3 +25,23 @@
foo(); foo();
setTimeout(_ => assertEquals(1, value)); setTimeout(_ => assertEquals(1, value));
})(); })();
(function() {
var value;
function foo(x) { return new Promise((resolve, reject) => resolve(x)); }
foo(1);
foo(1);
%OptimizeFunctionOnNextCall(foo);
foo(1).then(v => value = v);
setTimeout(_ => assertEquals(1, value));
})();
(function() {
var value;
function foo(x) { return new Promise((resolve, reject) => reject(x)); }
foo(1);
foo(1);
%OptimizeFunctionOnNextCall(foo);
foo(1).catch(v => value = v);
setTimeout(_ => assertEquals(1, value));
})();
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