Make control reducer revisit newly introduced merges.
authorjarin <jarin@chromium.org>
Mon, 5 Jan 2015 16:35:12 +0000 (08:35 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 5 Jan 2015 16:35:34 +0000 (16:35 +0000)
TEST=mjsunit/compiler/regress-445876
BUG=chromium:445876
LOG=N

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

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

src/compiler/control-reducer.cc
test/mjsunit/compiler/regress-445876.js [new file with mode: 0644]

index acb2f06..eef8a49 100644 (file)
@@ -196,6 +196,9 @@ class ControlReducerImpl {
       merge = graph()->NewNode(common_->Merge(2), merge, loop);
       end->ReplaceInput(0, merge);
       to_add = merge;
+      // Mark the node as visited so that we can revisit later.
+      EnsureStateSize(merge->id());
+      state_[merge->id()] = kVisited;
     } else {
       // Append a new input to the final merge at the end.
       merge->AppendInput(graph()->zone(), loop);
@@ -293,14 +296,17 @@ class ControlReducerImpl {
     if (replacement != node) Recurse(replacement);
   }
 
+  void EnsureStateSize(size_t id) {
+    if (id >= state_.size()) {
+      state_.resize((3 * id) / 2, kUnvisited);
+    }
+  }
+
   // Push a node onto the stack if its state is {kUnvisited} or {kRevisit}.
   bool Recurse(Node* node) {
     size_t id = static_cast<size_t>(node->id());
-    if (id < state_.size()) {
-      if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
-    } else {
-      state_.resize((3 * id) / 2, kUnvisited);
-    }
+    EnsureStateSize(id);
+    if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
     Push(node);
     return true;
   }
diff --git a/test/mjsunit/compiler/regress-445876.js b/test/mjsunit/compiler/regress-445876.js
new file mode 100644 (file)
index 0000000..30e10e5
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+  while (1) { s++; }
+  while (x) { s++; }
+}
+
+assertThrows(function () { f(1); });