From 489b6f7c6055cc208410b8bd9cf81deb89ddc26a Mon Sep 17 00:00:00 2001 From: jarin Date: Wed, 28 Jan 2015 08:16:09 -0800 Subject: [PATCH] [turbofan] Add missing deopt for the assignment in the for-in statement. BUG=chromium:416359 LOG=n R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/881303002 Cr-Commit-Position: refs/heads/master@{#26309} --- src/arm/full-codegen-arm.cc | 1 + src/arm64/full-codegen-arm64.cc | 1 + src/ast.h | 3 ++- src/compiler/ast-graph-builder.cc | 14 ++++++-------- src/compiler/ast-graph-builder.h | 3 ++- src/ia32/full-codegen-ia32.cc | 1 + src/mips/full-codegen-mips.cc | 1 + src/mips64/full-codegen-mips64.cc | 1 + src/ppc/full-codegen-ppc.cc | 1 + src/x64/full-codegen-x64.cc | 1 + src/x87/full-codegen-x87.cc | 1 + test/mjsunit/compiler/regress-416359.js | 10 ++++++++++ 12 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 test/mjsunit/compiler/regress-416359.js diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index dc663d9..1ab7f3c 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -1260,6 +1260,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 802179b..a7b06aa 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -1247,6 +1247,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/ast.h b/src/ast.h index 6da9a5f..4b5f0bd 100644 --- a/src/ast.h +++ b/src/ast.h @@ -933,11 +933,12 @@ class ForInStatement FINAL : public ForEachStatement { ForInType for_in_type() const { return for_in_type_; } void set_for_in_type(ForInType type) { for_in_type_ = type; } - static int num_ids() { return parent_num_ids() + 4; } + static int num_ids() { return parent_num_ids() + 5; } BailoutId BodyId() const { return BailoutId(local_id(0)); } BailoutId PrepareId() const { return BailoutId(local_id(1)); } BailoutId EnumId() const { return BailoutId(local_id(2)); } BailoutId ToObjectId() const { return BailoutId(local_id(3)); } + BailoutId AssignmentId() const { return BailoutId(local_id(4)); } BailoutId ContinueId() const OVERRIDE { return EntryId(); } BailoutId StackCheckId() const OVERRIDE { return BodyId(); } diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index d37ca7e..1390eeb 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -774,7 +774,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { } value = environment()->Pop(); // Bind value and do loop body. - VisitForInAssignment(stmt->each(), value); + VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); VisitIterationBody(stmt, &for_loop, 5); for_loop.EndBody(); // Inc counter and continue. @@ -1228,7 +1228,8 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { } -void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { +void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, + BailoutId bailout_id) { DCHECK(expr->IsValidReferenceExpression()); // Left-hand side can only be a property, a global or a variable slot. @@ -1239,8 +1240,7 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { switch (assign_type) { case VARIABLE: { Variable* var = expr->AsVariableProxy()->var(); - // TODO(jarin) Fill in the correct bailout id. - BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None()); + BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id); break; } case NAMED_PROPERTY: { @@ -1252,8 +1252,7 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { MakeUnique(property->key()->AsLiteral()->AsPropertyName()); Node* store = NewNode(javascript()->StoreNamed(strict_mode(), name), object, value); - // TODO(jarin) Fill in the correct bailout id. - PrepareFrameState(store, BailoutId::None()); + PrepareFrameState(store, bailout_id); break; } case KEYED_PROPERTY: { @@ -1265,8 +1264,7 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { value = environment()->Pop(); Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object, key, value); - // TODO(jarin) Fill in the correct bailout id. - PrepareFrameState(store, BailoutId::None()); + PrepareFrameState(store, bailout_id); break; } } diff --git a/src/compiler/ast-graph-builder.h b/src/compiler/ast-graph-builder.h index 6830c98..ce13374 100644 --- a/src/compiler/ast-graph-builder.h +++ b/src/compiler/ast-graph-builder.h @@ -197,7 +197,8 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { void VisitArithmeticExpression(BinaryOperation* expr); // Dispatched from VisitForInStatement. - void VisitForInAssignment(Expression* expr, Node* value); + void VisitForInAssignment(Expression* expr, Node* value, + BailoutId bailout_id); // Dispatched from VisitClassLiteral. void VisitClassLiteralContents(ClassLiteral* expr); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 3873c55..985cffc 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -1184,6 +1184,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 2aebbba..3b054c6 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -1247,6 +1247,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc index 733ff81..83bcf03 100644 --- a/src/mips64/full-codegen-mips64.cc +++ b/src/mips64/full-codegen-mips64.cc @@ -1242,6 +1242,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc index faf011f..b9870bb 100644 --- a/src/ppc/full-codegen-ppc.cc +++ b/src/ppc/full-codegen-ppc.cc @@ -1217,6 +1217,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 2fce910..6de2fc3 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -1218,6 +1218,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc index ed91743..cf4dd40 100644 --- a/src/x87/full-codegen-x87.cc +++ b/src/x87/full-codegen-x87.cc @@ -1173,6 +1173,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each()); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Generate code for the body of the loop. diff --git a/test/mjsunit/compiler/regress-416359.js b/test/mjsunit/compiler/regress-416359.js new file mode 100644 index 0000000..18cdc5e --- /dev/null +++ b/test/mjsunit/compiler/regress-416359.js @@ -0,0 +1,10 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +"use strict" +function f() { + for (x in {a:0}); +} + +assertThrows(f); -- 2.7.4