[turbofan] Add missing deopt for the assignment in the for-in statement.
authorjarin <jarin@chromium.org>
Wed, 28 Jan 2015 16:16:09 +0000 (08:16 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 28 Jan 2015 16:16:24 +0000 (16:16 +0000)
BUG=chromium:416359
LOG=n
R=mstarzinger@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26309}

12 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/ast.h
src/compiler/ast-graph-builder.cc
src/compiler/ast-graph-builder.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/ppc/full-codegen-ppc.cc
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/mjsunit/compiler/regress-416359.js [new file with mode: 0644]

index dc663d9..1ab7f3c 100644 (file)
@@ -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.
index 802179b..a7b06aa 100644 (file)
@@ -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.
index 6da9a5f..4b5f0bd 100644 (file)
--- 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(); }
 
index d37ca7e..1390eeb 100644 (file)
@@ -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;
     }
   }
index 6830c98..ce13374 100644 (file)
@@ -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);
index 3873c55..985cffc 100644 (file)
@@ -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.
index 2aebbba..3b054c6 100644 (file)
@@ -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.
index 733ff81..83bcf03 100644 (file)
@@ -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.
index faf011f..b9870bb 100644 (file)
@@ -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.
index 2fce910..6de2fc3 100644 (file)
@@ -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.
index ed91743..cf4dd40 100644 (file)
@@ -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 (file)
index 0000000..18cdc5e
--- /dev/null
@@ -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);