| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" | 
| 6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" | 
| 7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" | 
| 8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" | 
| 9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" | 
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" | 
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 245 }; | 245 }; | 
| 246 | 246 | 
| 247 | 247 | 
| 248 class Typer::RunVisitor : public Typer::Visitor { | 248 class Typer::RunVisitor : public Typer::Visitor { | 
| 249  public: | 249  public: | 
| 250   explicit RunVisitor(Typer* typer) | 250   explicit RunVisitor(Typer* typer) | 
| 251       : Visitor(typer), | 251       : Visitor(typer), | 
| 252         redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} | 252         redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} | 
| 253 | 253 | 
| 254   GenericGraphVisit::Control Post(Node* node) { | 254   GenericGraphVisit::Control Post(Node* node) { | 
| 255     if (node->op()->ValueOutputCount() > 0 && !NodeProperties::IsTyped(node)) { | 255     if (node->op()->ValueOutputCount() > 0) { | 
| 256       Bounds bounds = TypeNode(node); | 256       Bounds bounds = TypeNode(node); | 
| 257       NodeProperties::SetBounds(node, bounds); | 257       NodeProperties::SetBounds(node, bounds); | 
| 258       // Remember incompletely typed nodes for least fixpoint iteration. | 258       // Remember incompletely typed nodes for least fixpoint iteration. | 
| 259       if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node); | 259       if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node); | 
| 260     } | 260     } | 
| 261     return GenericGraphVisit::CONTINUE; | 261     return GenericGraphVisit::CONTINUE; | 
| 262   } | 262   } | 
| 263 | 263 | 
| 264   NodeSet redo; | 264   NodeSet redo; | 
| 265 }; | 265 }; | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 284   } | 284   } | 
| 285 | 285 | 
| 286   GenericGraphVisit::Control Post(Node* node) { | 286   GenericGraphVisit::Control Post(Node* node) { | 
| 287     return GenericGraphVisit::REENTER; | 287     return GenericGraphVisit::REENTER; | 
| 288   } | 288   } | 
| 289 }; | 289 }; | 
| 290 | 290 | 
| 291 | 291 | 
| 292 class Typer::WidenVisitor : public Typer::Visitor { | 292 class Typer::WidenVisitor : public Typer::Visitor { | 
| 293  public: | 293  public: | 
| 294   explicit WidenVisitor(Typer* typer) : Visitor(typer) {} | 294   explicit WidenVisitor(Typer* typer) | 
|  | 295       : Visitor(typer), | 
|  | 296         local_zone_(zone()->isolate()), | 
|  | 297         enabled_(graph()->NodeCount(), true, &local_zone_), | 
|  | 298         queue_(&local_zone_) {} | 
| 295 | 299 | 
| 296   GenericGraphVisit::Control Pre(Node* node) { | 300   void Run(NodeSet* nodes) { | 
| 297     if (node->op()->ValueOutputCount() > 0) { | 301     // Queue all the roots. | 
| 298       Bounds previous = BoundsOrNone(node); | 302     for (Node* node : *nodes) { | 
| 299       Bounds current = TypeNode(node); | 303       Queue(node); | 
|  | 304     } | 
| 300 | 305 | 
| 301       // Speed up termination in the presence of range types: | 306     while (!queue_.empty()) { | 
| 302       current.upper = Weaken(current.upper, previous.upper); | 307       Node* node = queue_.front(); | 
| 303       current.lower = Weaken(current.lower, previous.lower); | 308       queue_.pop(); | 
| 304 | 309 | 
| 305       DCHECK(previous.lower->Is(current.lower)); | 310       if (node->op()->ValueOutputCount() > 0) { | 
| 306       DCHECK(previous.upper->Is(current.upper)); | 311         // Enable future queuing (and thus re-typing) of this node. | 
|  | 312         enabled_[node->id()] = true; | 
| 307 | 313 | 
| 308       NodeProperties::SetBounds(node, current); | 314         // Compute the new type. | 
| 309       // Stop when nothing changed (but allow re-entry in case it does later). | 315         Bounds previous = BoundsOrNone(node); | 
| 310       return previous.Narrows(current) && current.Narrows(previous) | 316         Bounds current = TypeNode(node); | 
| 311                  ? GenericGraphVisit::DEFER | 317 | 
| 312                  : GenericGraphVisit::REENTER; | 318         // Speed up termination in the presence of range types: | 
| 313     } else { | 319         current.upper = Weaken(current.upper, previous.upper); | 
| 314       return GenericGraphVisit::SKIP; | 320         current.lower = Weaken(current.lower, previous.lower); | 
|  | 321 | 
|  | 322         // Types should not get less precise. | 
|  | 323         DCHECK(previous.lower->Is(current.lower)); | 
|  | 324         DCHECK(previous.upper->Is(current.upper)); | 
|  | 325 | 
|  | 326         NodeProperties::SetBounds(node, current); | 
|  | 327         // If something changed, push all uses into the queue. | 
|  | 328         if (!(previous.Narrows(current) && current.Narrows(previous))) { | 
|  | 329           for (Node* use : node->uses()) { | 
|  | 330             Queue(use); | 
|  | 331           } | 
|  | 332         } | 
|  | 333       } | 
|  | 334       // If there is no value output, we deliberately leave the node disabled | 
|  | 335       // for queuing - there is no need to type it. | 
| 315     } | 336     } | 
| 316   } | 337   } | 
| 317 | 338 | 
| 318   GenericGraphVisit::Control Post(Node* node) { | 339   void Queue(Node* node) { | 
| 319     return GenericGraphVisit::REENTER; | 340     // If the node is enabled for queuing, push it to the queue and disable it | 
|  | 341     // (to avoid queuing it multiple times). | 
|  | 342     if (enabled_[node->id()]) { | 
|  | 343       queue_.push(node); | 
|  | 344       enabled_[node->id()] = false; | 
|  | 345     } | 
| 320   } | 346   } | 
|  | 347 | 
|  | 348  private: | 
|  | 349   Zone local_zone_; | 
|  | 350   BoolVector enabled_; | 
|  | 351   ZoneQueue<Node*> queue_; | 
| 321 }; | 352 }; | 
| 322 | 353 | 
| 323 | 354 | 
| 324 void Typer::Run() { | 355 void Typer::Run() { | 
| 325   RunVisitor typing(this); | 356   RunVisitor typing(this); | 
| 326   graph_->VisitNodeInputsFromEnd(&typing); | 357   graph_->VisitNodeInputsFromEnd(&typing); | 
| 327   // Find least fixpoint. | 358   // Find least fixpoint. | 
| 328   WidenVisitor widen(this); | 359   WidenVisitor widen(this); | 
| 329   for (NodeSetIter it = typing.redo.begin(); it != typing.redo.end(); ++it) { | 360   widen.Run(&typing.redo); | 
| 330     graph_->VisitNodeUsesFrom(*it, &widen); |  | 
| 331   } |  | 
| 332 } | 361 } | 
| 333 | 362 | 
| 334 | 363 | 
| 335 void Typer::Narrow(Node* start) { | 364 void Typer::Narrow(Node* start) { | 
| 336   NarrowVisitor typing(this); | 365   NarrowVisitor typing(this); | 
| 337   graph_->VisitNodeUsesFrom(start, &typing); | 366   graph_->VisitNodeUsesFrom(start, &typing); | 
| 338 } | 367 } | 
| 339 | 368 | 
| 340 | 369 | 
| 341 void Typer::Decorator::Decorate(Node* node) { | 370 void Typer::Decorator::Decorate(Node* node) { | 
| (...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1879         return typer_->float64_array_fun_; | 1908         return typer_->float64_array_fun_; | 
| 1880       } | 1909       } | 
| 1881     } | 1910     } | 
| 1882   } | 1911   } | 
| 1883   return Type::Constant(value, zone()); | 1912   return Type::Constant(value, zone()); | 
| 1884 } | 1913 } | 
| 1885 | 1914 | 
| 1886 } | 1915 } | 
| 1887 } | 1916 } | 
| 1888 }  // namespace v8::internal::compiler | 1917 }  // namespace v8::internal::compiler | 
| OLD | NEW | 
|---|