Commit 6040d5c0 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Fix missing bailout point before calls.

In order to properly (lazy) bailout when converting the receiver for
sloppy mode functions (using the newly added JSConvertReceiver
operator), we need to have a bailout location right before every call
(also right before every %_Call and %_CallFunction), otherwise if the
JSConvertReceiver just reuses the lazy bailout frame state from the
JSCallFunction node, it will skip the whole function in case of lazy
bailout.

Note it should be impossible to trigger this currently because we do not
yet support AllocationSite code dependencies in TurboFan, which can
trigger this kind of lazy bailout; therefore it's not possible to write
a regression test (yet).

R=yangguo@chromium.org
BUG=v8:4493
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#31668}
parent a8cddabf
......@@ -1896,10 +1896,11 @@ class Call final : public Expression {
allocation_site_ = site;
}
static int num_ids() { return parent_num_ids() + 3; }
static int num_ids() { return parent_num_ids() + 4; }
BailoutId ReturnId() const { return BailoutId(local_id(0)); }
BailoutId EvalId() const { return BailoutId(local_id(1)); }
BailoutId LookupId() const { return BailoutId(local_id(2)); }
BailoutId CallId() const { return BailoutId(local_id(3)); }
bool is_uninitialized() const {
return IsUninitializedField::decode(bit_field_);
......
......@@ -394,8 +394,9 @@ class AstGraphBuilder::FrameStateBeforeAndAfter {
: builder_->environment()->Checkpoint(id_before);
}
void AddToNode(Node* node, BailoutId id_after,
OutputFrameStateCombine combine) {
void AddToNode(
Node* node, BailoutId id_after,
OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) {
int count = OperatorProperties::GetFrameStateInputCount(node->op());
DCHECK_LE(count, 2);
......@@ -1962,21 +1963,24 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
if (subexpr->IsSpread()) {
VisitForValue(subexpr->AsSpread()->expression());
FrameStateBeforeAndAfter states(this,
subexpr->AsSpread()->expression()->id());
Node* iterable = environment()->Pop();
Node* function = BuildLoadNativeContextField(
Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX);
result = NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS,
language_mode()),
function, array, iterable);
states.AddToNode(result, expr->GetIdForElement(array_index));
} else {
VisitForValue(subexpr);
Node* value = environment()->Pop();
const Operator* op =
javascript()->CallRuntime(Runtime::kAppendElement, 2);
result = NewNode(op, array, value);
PrepareFrameState(result, expr->GetIdForElement(array_index));
}
PrepareFrameState(result, expr->GetIdForElement(array_index));
environment()->Push(result);
}
......@@ -2489,9 +2493,10 @@ void AstGraphBuilder::VisitCall(Call* expr) {
VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
const Operator* call = javascript()->CallFunction(
args->length() + 2, flags, language_mode(), feedback, receiver_hint);
FrameStateBeforeAndAfter states(this, expr->CallId());
Node* value = ProcessArguments(call, args->length() + 2);
environment()->Push(value->InputAt(0)); // The callee passed to the call.
PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
environment()->Drop(1);
ast_context()->ProduceValue(value);
}
......@@ -2561,8 +2566,9 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
// Create node to perform the JS runtime call.
const Operator* call =
javascript()->CallFunction(args->length() + 2, flags, language_mode());
FrameStateBeforeAndAfter states(this, expr->CallId());
Node* value = ProcessArguments(call, args->length() + 2);
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
......
......@@ -569,6 +569,7 @@ void JSGenericLowering::LowerJSCallFunction(Node* node) {
void JSGenericLowering::LowerJSCallRuntime(Node* node) {
const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
AdjustFrameStatesForCall(node);
ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
}
......
......@@ -56,7 +56,12 @@ class JSCallFunctionAccessor {
return value_inputs - 2;
}
Node* frame_state() { return NodeProperties::GetFrameStateInput(call_, 0); }
Node* frame_state_before() {
return NodeProperties::GetFrameStateInput(call_, 1);
}
Node* frame_state_after() {
return NodeProperties::GetFrameStateInput(call_, 0);
}
private:
Node* call_;
......@@ -237,9 +242,9 @@ Node* JSInliner::CreateArgumentsAdaptorFrameState(
jsgraph_->common()->StateValues(static_cast<int>(params.size()));
Node* params_node = jsgraph_->graph()->NewNode(
op_param, static_cast<int>(params.size()), &params.front());
return jsgraph_->graph()->NewNode(op, params_node, node0, node0,
jsgraph_->UndefinedConstant(),
call->jsfunction(), call->frame_state());
return jsgraph_->graph()->NewNode(
op, params_node, node0, node0, jsgraph_->UndefinedConstant(),
call->jsfunction(), call->frame_state_after());
}
......@@ -295,7 +300,7 @@ Reduction JSInliner::ReduceJSCallFunction(Node* node,
// TODO(turbofan): TranslatedState::GetAdaptedArguments() currently relies on
// not inlining recursive functions. We might want to relax that at some
// point.
for (Node* frame_state = call.frame_state();
for (Node* frame_state = call.frame_state_after();
frame_state->opcode() == IrOpcode::kFrameState;
frame_state = frame_state->InputAt(kFrameStateOuterStateInput)) {
FrameStateInfo const& info = OpParameter<FrameStateInfo>(frame_state);
......@@ -409,29 +414,33 @@ Reduction JSInliner::ReduceJSCallFunction(Node* node,
Node* start = visitor.GetCopy(graph.start());
Node* end = visitor.GetCopy(graph.end());
Node* frame_state = call.frame_state();
// Insert argument adaptor frame if required. The callees formal parameter
// count (i.e. value outputs of start node minus target, receiver & context)
// have to match the number of arguments passed to the call.
DCHECK_EQ(static_cast<int>(parameter_count),
start->op()->ValueOutputCount() - 3);
if (call.formal_arguments() != parameter_count) {
frame_state = CreateArgumentsAdaptorFrameState(&call, info.shared_info());
}
Node* frame_state = call.frame_state_after();
// Insert a JSConvertReceiver node for sloppy callees. Note that the context
// passed into this node has to be the callees context (loaded above).
// passed into this node has to be the callees context (loaded above). Note
// that the frame state passed to the JSConvertReceiver must be the frame
// state _before_ the call; it is not necessary to fiddle with the receiver
// in that frame state tho, as the conversion of the receiver can be repeated
// any number of times, it's not observable.
if (is_sloppy(info.language_mode()) && !function->shared()->native()) {
const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
Node* effect = NodeProperties::GetEffectInput(node);
Node* convert = jsgraph_->graph()->NewNode(
jsgraph_->javascript()->ConvertReceiver(p.convert_mode()),
call.receiver(), context, frame_state, effect, start);
call.receiver(), context, call.frame_state_before(), effect, start);
NodeProperties::ReplaceValueInput(node, convert, 1);
NodeProperties::ReplaceEffectInput(node, convert);
}
// Insert argument adaptor frame if required. The callees formal parameter
// count (i.e. value outputs of start node minus target, receiver & context)
// have to match the number of arguments passed to the call.
DCHECK_EQ(static_cast<int>(parameter_count),
start->op()->ValueOutputCount() - 3);
if (call.formal_arguments() != parameter_count) {
frame_state = CreateArgumentsAdaptorFrameState(&call, info.shared_info());
}
return InlineCall(node, context, frame_state, start, end);
}
......
......@@ -1587,6 +1587,7 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
if (p.AllowTailCalls()) {
flags |= CallDescriptor::kSupportsTailCalls;
}
NodeProperties::RemoveFrameStateInput(node, 1);
NodeProperties::ChangeOp(node,
common()->Call(Linkage::GetJSCallDescriptor(
graph()->zone(), false, 1 + arity, flags)));
......
......@@ -242,8 +242,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
return 0;
case Runtime::kInlineArguments:
case Runtime::kInlineArgumentsLength:
case Runtime::kInlineCall:
case Runtime::kInlineCallFunction:
case Runtime::kInlineDefaultConstructorCallSuper:
case Runtime::kInlineGetCallerJSFunction:
case Runtime::kInlineGetPrototype:
......@@ -259,6 +257,8 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
case Runtime::kInlineToPrimitive:
case Runtime::kInlineToString:
return 1;
case Runtime::kInlineCall:
case Runtime::kInlineCallFunction:
case Runtime::kInlineDeoptimizeNow:
case Runtime::kInlineThrowNotDateError:
return 2;
......
......@@ -163,6 +163,13 @@ void NodeProperties::ReplaceFrameStateInput(Node* node, int index,
}
// static
void NodeProperties::RemoveFrameStateInput(Node* node, int index) {
DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
node->RemoveInput(FirstFrameStateIndex(node) + index);
}
// static
void NodeProperties::RemoveNonValueInputs(Node* node) {
node->TrimInputCount(node->op()->ValueInputCount());
......
......@@ -84,6 +84,7 @@ class NodeProperties final {
static void ReplaceControlInput(Node* node, Node* control);
static void ReplaceEffectInput(Node* node, Node* effect, int index = 0);
static void ReplaceFrameStateInput(Node* node, int index, Node* frame_state);
static void RemoveFrameStateInput(Node* node, int index);
static void RemoveNonValueInputs(Node* node);
// Merge the control node {node} into the end of the graph, introducing a
......
......@@ -34,8 +34,12 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
case IrOpcode::kJSStrictNotEqual:
return 0;
// Calls
// We record the frame state immediately before and immediately after every
// function call.
case IrOpcode::kJSCallFunction:
return 2;
// Construct calls
case IrOpcode::kJSCallConstruct:
// Compare operations
......
......@@ -2957,6 +2957,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
......@@ -3898,6 +3899,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to r1.
int const argc = args->length() - 2;
__ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
......@@ -3921,6 +3923,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(r0, &runtime);
......
......@@ -2660,6 +2660,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
......@@ -3613,6 +3614,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to x1.
int const argc = args->length() - 2;
__ Peek(x1, (argc + 1) * kXRegSize);
......@@ -3637,6 +3639,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(x0, &runtime);
......
......@@ -2848,6 +2848,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
......@@ -3797,6 +3798,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to edi.
int const argc = args->length() - 2;
__ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
......@@ -3820,6 +3822,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(eax, &runtime);
......
......@@ -2947,6 +2947,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Record source position of the IC call.
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
......@@ -3913,6 +3914,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to a1.
int const argc = args->length() - 2;
__ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize));
......@@ -3936,6 +3938,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(v0, &runtime);
......
......@@ -2950,6 +2950,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Record source position of the IC call.
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
......@@ -3916,6 +3917,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to a1.
int const argc = args->length() - 2;
__ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize));
......@@ -3939,6 +3941,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(v0, &runtime);
......
......@@ -2950,6 +2950,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
......@@ -3899,6 +3900,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to r4.
int const argc = args->length() - 2;
__ LoadP(r4, MemOperand(sp, (argc + 1) * kPointerSize));
......@@ -3922,6 +3924,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(r3, &runtime);
......
......@@ -2840,6 +2840,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
......@@ -3793,6 +3794,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to rdi.
int const argc = args->length() - 2;
__ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize));
......@@ -3816,6 +3818,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), TOS_REG);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(rax, &runtime);
......
......@@ -2841,6 +2841,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
......@@ -3790,6 +3791,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
// Move target to edi.
int const argc = args->length() - 2;
__ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
......@@ -3813,6 +3815,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
}
VisitForAccumulatorValue(args->last()); // Function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
Label runtime, done;
// Check for non-function argument (including proxy).
__ JumpIfSmi(eax, &runtime);
......
......@@ -85,12 +85,13 @@ TEST_F(JSBuiltinReducerTest, MathMax0) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Node* call = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, language_mode),
function, UndefinedConstant(), frame_state, frame_state, effect,
control);
function, UndefinedConstant(), context, frame_state, frame_state,
effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -104,14 +105,15 @@ TEST_F(JSBuiltinReducerTest, MathMax1) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kNumberTypes) {
Node* p0 = Parameter(t0, 0);
Node* call = graph()->NewNode(
javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode),
function, UndefinedConstant(), p0, frame_state, frame_state, effect,
control);
function, UndefinedConstant(), p0, context, frame_state, frame_state,
effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -126,6 +128,7 @@ TEST_F(JSBuiltinReducerTest, MathMax2) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kIntegral32Types) {
......@@ -135,8 +138,8 @@ TEST_F(JSBuiltinReducerTest, MathMax2) {
Node* call =
graph()->NewNode(javascript()->CallFunction(
4, NO_CALL_FUNCTION_FLAGS, language_mode),
function, UndefinedConstant(), p0, p1, frame_state,
frame_state, effect, control);
function, UndefinedConstant(), p0, p1, context,
frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -157,6 +160,7 @@ TEST_F(JSBuiltinReducerTest, MathImul) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kIntegral32Types) {
......@@ -166,8 +170,8 @@ TEST_F(JSBuiltinReducerTest, MathImul) {
Node* call =
graph()->NewNode(javascript()->CallFunction(
4, NO_CALL_FUNCTION_FLAGS, language_mode),
function, UndefinedConstant(), p0, p1, frame_state,
frame_state, effect, control);
function, UndefinedConstant(), p0, p1, context,
frame_state, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -187,14 +191,15 @@ TEST_F(JSBuiltinReducerTest, MathFround) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
TRACED_FOREACH(Type*, t0, kNumberTypes) {
Node* p0 = Parameter(t0, 0);
Node* call = graph()->NewNode(
javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode),
function, UndefinedConstant(), p0, frame_state, frame_state, effect,
control);
function, UndefinedConstant(), p0, context, frame_state, frame_state,
effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......
......@@ -82,10 +82,10 @@ TEST_F(JSContextRelaxationTest,
ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
......@@ -101,10 +101,10 @@ TEST_F(JSContextRelaxationTest,
ShallowFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_FALSE(r.Changed());
EXPECT_EQ(context, NodeProperties::GetContextInput(node));
......@@ -120,10 +120,10 @@ TEST_F(JSContextRelaxationTest,
DeepFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
......@@ -139,10 +139,10 @@ TEST_F(JSContextRelaxationTest,
DeepFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state, frame_state, effect, control);
Reduction const r = Reduce(node);
EXPECT_FALSE(r.Changed());
EXPECT_EQ(context, NodeProperties::GetContextInput(node));
......@@ -161,10 +161,10 @@ TEST_F(JSContextRelaxationTest,
op, graph()->start(), graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state_2, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
......@@ -187,10 +187,10 @@ TEST_F(JSContextRelaxationTest,
frame_state_1, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state_2, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
......@@ -211,10 +211,10 @@ TEST_F(JSContextRelaxationTest,
graph()->NewNode(op, graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state_2, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
......@@ -237,10 +237,10 @@ TEST_F(JSContextRelaxationTest,
frame_state_1, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state_2, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node));
......@@ -260,10 +260,10 @@ TEST_F(JSContextRelaxationTest,
op, graph()->start(), graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state_2, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_TRUE(r.Changed());
EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node));
......@@ -283,10 +283,10 @@ TEST_F(JSContextRelaxationTest,
graph()->NewNode(op, graph()->start(), outer_context, effect, control);
Node* const frame_state_2 =
ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
Node* node =
graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS,
STRICT, VectorSlotPair()),
input0, input1, context, frame_state_2, effect, control);
Node* node = graph()->NewNode(
javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, STRICT,
VectorSlotPair()),
input0, input1, context, frame_state_2, frame_state_2, effect, control);
Reduction const r = Reduce(node);
EXPECT_FALSE(r.Changed());
EXPECT_EQ(context, NodeProperties::GetContextInput(node));
......
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