OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 } | 415 } |
416 } | 416 } |
417 | 417 |
418 int visited_count_; | 418 int visited_count_; |
419 ZoneList<HBasicBlock*> stack_; | 419 ZoneList<HBasicBlock*> stack_; |
420 BitVector reachable_; | 420 BitVector reachable_; |
421 HBasicBlock* dont_visit_; | 421 HBasicBlock* dont_visit_; |
422 }; | 422 }; |
423 | 423 |
424 | 424 |
425 void HGraph::Verify() const { | 425 void HGraph::Verify(bool do_full_verify) const { |
426 for (int i = 0; i < blocks_.length(); i++) { | 426 for (int i = 0; i < blocks_.length(); i++) { |
427 HBasicBlock* block = blocks_.at(i); | 427 HBasicBlock* block = blocks_.at(i); |
428 | 428 |
429 block->Verify(); | 429 block->Verify(); |
430 | 430 |
431 // Check that every block contains at least one node and that only the last | 431 // Check that every block contains at least one node and that only the last |
432 // node is a control instruction. | 432 // node is a control instruction. |
433 HInstruction* current = block->first(); | 433 HInstruction* current = block->first(); |
434 ASSERT(current != NULL && current->IsBlockEntry()); | 434 ASSERT(current != NULL && current->IsBlockEntry()); |
435 while (current != NULL) { | 435 while (current != NULL) { |
(...skipping 30 matching lines...) Expand all Loading... |
466 HBasicBlock* predecessor = block->predecessors()->at(k); | 466 HBasicBlock* predecessor = block->predecessors()->at(k); |
467 ASSERT(predecessor->end()->IsGoto()); | 467 ASSERT(predecessor->end()->IsGoto()); |
468 ASSERT(predecessor->last_environment()->ast_id() == id); | 468 ASSERT(predecessor->last_environment()->ast_id() == id); |
469 } | 469 } |
470 } | 470 } |
471 } | 471 } |
472 | 472 |
473 // Check special property of first block to have no predecessors. | 473 // Check special property of first block to have no predecessors. |
474 ASSERT(blocks_.at(0)->predecessors()->is_empty()); | 474 ASSERT(blocks_.at(0)->predecessors()->is_empty()); |
475 | 475 |
476 // Check that the graph is fully connected. | 476 if (do_full_verify) { |
477 ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); | 477 // Check that the graph is fully connected. |
478 ASSERT(analyzer.visited_count() == blocks_.length()); | 478 ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); |
| 479 ASSERT(analyzer.visited_count() == blocks_.length()); |
479 | 480 |
480 // Check that entry block dominator is NULL. | 481 // Check that entry block dominator is NULL. |
481 ASSERT(entry_block_->dominator() == NULL); | 482 ASSERT(entry_block_->dominator() == NULL); |
482 | 483 |
483 // Check dominators. | 484 // Check dominators. |
484 for (int i = 0; i < blocks_.length(); ++i) { | 485 for (int i = 0; i < blocks_.length(); ++i) { |
485 HBasicBlock* block = blocks_.at(i); | 486 HBasicBlock* block = blocks_.at(i); |
486 if (block->dominator() == NULL) { | 487 if (block->dominator() == NULL) { |
487 // Only start block may have no dominator assigned to. | 488 // Only start block may have no dominator assigned to. |
488 ASSERT(i == 0); | 489 ASSERT(i == 0); |
489 } else { | 490 } else { |
490 // Assert that block is unreachable if dominator must not be visited. | 491 // Assert that block is unreachable if dominator must not be visited. |
491 ReachabilityAnalyzer dominator_analyzer(entry_block_, | 492 ReachabilityAnalyzer dominator_analyzer(entry_block_, |
492 blocks_.length(), | 493 blocks_.length(), |
493 block->dominator()); | 494 block->dominator()); |
494 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); | 495 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); |
| 496 } |
495 } | 497 } |
496 } | 498 } |
497 } | 499 } |
498 | 500 |
499 #endif | 501 #endif |
500 | 502 |
501 | 503 |
502 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, | 504 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, |
503 Object* value) { | 505 Object* value) { |
504 if (!pointer->is_set()) { | 506 if (!pointer->is_set()) { |
(...skipping 1808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 | 2315 |
2314 if (current_block() != NULL) { | 2316 if (current_block() != NULL) { |
2315 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); | 2317 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); |
2316 current_block()->FinishExit(instr); | 2318 current_block()->FinishExit(instr); |
2317 set_current_block(NULL); | 2319 set_current_block(NULL); |
2318 } | 2320 } |
2319 } | 2321 } |
2320 | 2322 |
2321 graph()->OrderBlocks(); | 2323 graph()->OrderBlocks(); |
2322 graph()->AssignDominators(); | 2324 graph()->AssignDominators(); |
| 2325 |
| 2326 #ifdef DEBUG |
| 2327 // Do a full verify after building the graph and computing dominators. |
| 2328 graph()->Verify(true); |
| 2329 #endif |
| 2330 |
2323 graph()->PropagateDeoptimizingMark(); | 2331 graph()->PropagateDeoptimizingMark(); |
2324 graph()->EliminateRedundantPhis(); | 2332 graph()->EliminateRedundantPhis(); |
2325 if (!graph()->CheckPhis()) { | 2333 if (!graph()->CheckPhis()) { |
2326 Bailout("Unsupported phi use of arguments object"); | 2334 Bailout("Unsupported phi use of arguments object"); |
2327 return NULL; | 2335 return NULL; |
2328 } | 2336 } |
2329 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); | 2337 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); |
2330 if (!graph()->CollectPhis()) { | 2338 if (!graph()->CollectPhis()) { |
2331 Bailout("Unsupported phi use of uninitialized constant"); | 2339 Bailout("Unsupported phi use of uninitialized constant"); |
2332 return NULL; | 2340 return NULL; |
(...skipping 4482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6815 | 6823 |
6816 if (FLAG_trace_hydrogen) { | 6824 if (FLAG_trace_hydrogen) { |
6817 if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_); | 6825 if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_); |
6818 if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_); | 6826 if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_); |
6819 if (allocator_ != NULL) { | 6827 if (allocator_ != NULL) { |
6820 HTracer::Instance()->TraceLiveRanges(name_, allocator_); | 6828 HTracer::Instance()->TraceLiveRanges(name_, allocator_); |
6821 } | 6829 } |
6822 } | 6830 } |
6823 | 6831 |
6824 #ifdef DEBUG | 6832 #ifdef DEBUG |
6825 if (graph_ != NULL) graph_->Verify(); | 6833 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
6826 if (allocator_ != NULL) allocator_->Verify(); | 6834 if (allocator_ != NULL) allocator_->Verify(); |
6827 #endif | 6835 #endif |
6828 } | 6836 } |
6829 | 6837 |
6830 } } // namespace v8::internal | 6838 } } // namespace v8::internal |
OLD | NEW |