From aeda76c5cfa9181fff5ed7140e726f96ec883cc3 Mon Sep 17 00:00:00 2001 From: titzer Date: Tue, 9 Dec 2014 07:09:52 -0800 Subject: [PATCH] [turbofan] Fix control reducer bug with NTLs. R=bmeurer@chromium.org BUG= Review URL: https://codereview.chromium.org/789773002 Cr-Commit-Position: refs/heads/master@{#25725} --- src/compiler/control-reducer.cc | 9 ++++++--- test/mjsunit/regress-ntl.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 test/mjsunit/regress-ntl.js diff --git a/src/compiler/control-reducer.cc b/src/compiler/control-reducer.cc index 236ce4b..e738ccf 100644 --- a/src/compiler/control-reducer.cc +++ b/src/compiler/control-reducer.cc @@ -107,7 +107,7 @@ class ControlReducerImpl { // We use a stack of (Node, UseIter) pairs to avoid O(n^2) traversal. typedef std::pair FwIter; - ZoneDeque fw_stack(zone_); + ZoneVector 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 index 0000000..993599e --- /dev/null +++ b/test/mjsunit/regress-ntl.js @@ -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); -- 2.7.4