| Index: src/compiler/typer.cc
 | 
| diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
 | 
| index 994a6384fdeba69e2cc9e13fee934e80e521ef15..6b32258d111bdc277bce729b4b6324487654e051 100644
 | 
| --- a/src/compiler/typer.cc
 | 
| +++ b/src/compiler/typer.cc
 | 
| @@ -252,7 +252,7 @@ class Typer::RunVisitor : public Typer::Visitor {
 | 
|          redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
 | 
|  
 | 
|    GenericGraphVisit::Control Post(Node* node) {
 | 
| -    if (node->op()->ValueOutputCount() > 0 && !NodeProperties::IsTyped(node)) {
 | 
| +    if (node->op()->ValueOutputCount() > 0) {
 | 
|        Bounds bounds = TypeNode(node);
 | 
|        NodeProperties::SetBounds(node, bounds);
 | 
|        // Remember incompletely typed nodes for least fixpoint iteration.
 | 
| @@ -291,33 +291,64 @@ class Typer::NarrowVisitor : public Typer::Visitor {
 | 
|  
 | 
|  class Typer::WidenVisitor : public Typer::Visitor {
 | 
|   public:
 | 
| -  explicit WidenVisitor(Typer* typer) : Visitor(typer) {}
 | 
| +  explicit WidenVisitor(Typer* typer)
 | 
| +      : Visitor(typer),
 | 
| +        local_zone_(zone()->isolate()),
 | 
| +        enabled_(graph()->NodeCount(), true, &local_zone_),
 | 
| +        queue_(&local_zone_) {}
 | 
| +
 | 
| +  void Run(NodeSet* nodes) {
 | 
| +    // Queue all the roots.
 | 
| +    for (Node* node : *nodes) {
 | 
| +      Queue(node);
 | 
| +    }
 | 
|  
 | 
| -  GenericGraphVisit::Control Pre(Node* node) {
 | 
| -    if (node->op()->ValueOutputCount() > 0) {
 | 
| -      Bounds previous = BoundsOrNone(node);
 | 
| -      Bounds current = TypeNode(node);
 | 
| +    while (!queue_.empty()) {
 | 
| +      Node* node = queue_.front();
 | 
| +      queue_.pop();
 | 
|  
 | 
| -      // Speed up termination in the presence of range types:
 | 
| -      current.upper = Weaken(current.upper, previous.upper);
 | 
| -      current.lower = Weaken(current.lower, previous.lower);
 | 
| +      if (node->op()->ValueOutputCount() > 0) {
 | 
| +        // Enable future queuing (and thus re-typing) of this node.
 | 
| +        enabled_[node->id()] = true;
 | 
|  
 | 
| -      DCHECK(previous.lower->Is(current.lower));
 | 
| -      DCHECK(previous.upper->Is(current.upper));
 | 
| +        // Compute the new type.
 | 
| +        Bounds previous = BoundsOrNone(node);
 | 
| +        Bounds current = TypeNode(node);
 | 
|  
 | 
| -      NodeProperties::SetBounds(node, current);
 | 
| -      // Stop when nothing changed (but allow re-entry in case it does later).
 | 
| -      return previous.Narrows(current) && current.Narrows(previous)
 | 
| -                 ? GenericGraphVisit::DEFER
 | 
| -                 : GenericGraphVisit::REENTER;
 | 
| -    } else {
 | 
| -      return GenericGraphVisit::SKIP;
 | 
| +        // Speed up termination in the presence of range types:
 | 
| +        current.upper = Weaken(current.upper, previous.upper);
 | 
| +        current.lower = Weaken(current.lower, previous.lower);
 | 
| +
 | 
| +        // Types should not get less precise.
 | 
| +        DCHECK(previous.lower->Is(current.lower));
 | 
| +        DCHECK(previous.upper->Is(current.upper));
 | 
| +
 | 
| +        NodeProperties::SetBounds(node, current);
 | 
| +        // If something changed, push all uses into the queue.
 | 
| +        if (!(previous.Narrows(current) && current.Narrows(previous))) {
 | 
| +          for (Node* use : node->uses()) {
 | 
| +            Queue(use);
 | 
| +          }
 | 
| +        }
 | 
| +      }
 | 
| +      // If there is no value output, we deliberately leave the node disabled
 | 
| +      // for queuing - there is no need to type it.
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  GenericGraphVisit::Control Post(Node* node) {
 | 
| -    return GenericGraphVisit::REENTER;
 | 
| +  void Queue(Node* node) {
 | 
| +    // If the node is enabled for queuing, push it to the queue and disable it
 | 
| +    // (to avoid queuing it multiple times).
 | 
| +    if (enabled_[node->id()]) {
 | 
| +      queue_.push(node);
 | 
| +      enabled_[node->id()] = false;
 | 
| +    }
 | 
|    }
 | 
| +
 | 
| + private:
 | 
| +  Zone local_zone_;
 | 
| +  BoolVector enabled_;
 | 
| +  ZoneQueue<Node*> queue_;
 | 
|  };
 | 
|  
 | 
|  
 | 
| @@ -326,9 +357,7 @@ void Typer::Run() {
 | 
|    graph_->VisitNodeInputsFromEnd(&typing);
 | 
|    // Find least fixpoint.
 | 
|    WidenVisitor widen(this);
 | 
| -  for (NodeSetIter it = typing.redo.begin(); it != typing.redo.end(); ++it) {
 | 
| -    graph_->VisitNodeUsesFrom(*it, &widen);
 | 
| -  }
 | 
| +  widen.Run(&typing.redo);
 | 
|  }
 | 
|  
 | 
|  
 | 
| 
 |