[turbofan] Fix control reducer bug with NTLs.
authortitzer <titzer@chromium.org>
Tue, 9 Dec 2014 15:09:52 +0000 (07:09 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 9 Dec 2014 15:09:59 +0000 (15:09 +0000)
R=bmeurer@chromium.org
BUG=

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

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

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

index 236ce4b..e738ccf 100644 (file)
@@ -107,7 +107,7 @@ class ControlReducerImpl {
 
     // We use a stack of (Node, UseIter) pairs to avoid O(n^2) traversal.
     typedef std::pair<Node*, UseIter> FwIter;
-    ZoneDeque<FwIter> fw_stack(zone_);
+    ZoneVector<FwIter> fw_stack(zone_);
     fw_stack.push_back(FwIter(start, start->uses().begin()));
 
     while (!fw_stack.empty()) {
@@ -123,8 +123,11 @@ class ControlReducerImpl {
           marked.SetReachableFromEnd(added);
           AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1);
 
-          // The use list of {succ} might have changed.
-          fw_stack[fw_stack.size() - 1] = FwIter(succ, succ->uses().begin());
+          // Reset the use iterators for the entire stack.
+          for (size_t i = 0; i < fw_stack.size(); i++) {
+            FwIter& iter = fw_stack[i];
+            fw_stack[i] = FwIter(iter.first, iter.first->uses().begin());
+          }
           pop = false;  // restart traversing successors of this node.
           break;
         }
diff --git a/test/mjsunit/regress-ntl.js b/test/mjsunit/regress-ntl.js
new file mode 100644 (file)
index 0000000..993599e
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2014 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 mod1() {
+  var v_1 = 1;
+  var v_2 = 1;
+  v_1++;
+  v_2 = {valueOf: function() { throw "gagh"; }};
+
+  function bug1() {
+    for (var i = 0; i < 1; v_2++) {
+      if (v_1 == 1) ;
+    }
+  }
+
+  return bug1;
+}
+
+var f = mod1();
+assertThrows(f);
+%OptimizeFunctionOnNextCall(f);
+assertThrows(f);
+
+
+var v_3 = 1;
+var v_4 = 1;
+v_3++;
+v_4 = {valueOf: function() { throw "gagh"; }};
+
+function bug2() {
+  for (var i = 0; i < 1; v_4++) {
+    if (v_3 == 1) ;
+  }
+}
+
+assertThrows(bug2);
+%OptimizeFunctionOnNextCall(bug2);
+assertThrows(bug2);