| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 HEnvironment* environment = last_environment(); | 169 HEnvironment* environment = last_environment(); |
| 170 DCHECK(ast_id.IsNone() || | 170 DCHECK(ast_id.IsNone() || |
| 171 ast_id == BailoutId::StubEntry() || | 171 ast_id == BailoutId::StubEntry() || |
| 172 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 172 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
| 173 | 173 |
| 174 int push_count = environment->push_count(); | 174 int push_count = environment->push_count(); |
| 175 int pop_count = environment->pop_count(); | 175 int pop_count = environment->pop_count(); |
| 176 | 176 |
| 177 HSimulate* instr = | 177 HSimulate* instr = |
| 178 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); | 178 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); |
| 179 #ifdef DEBUG | 179 #if DCHECK_IS_ON |
| 180 instr->set_closure(environment->closure()); | 180 instr->set_closure(environment->closure()); |
| 181 #endif | 181 #endif |
| 182 // Order of pushed values: newest (top of stack) first. This allows | 182 // Order of pushed values: newest (top of stack) first. This allows |
| 183 // HSimulate::MergeWith() to easily append additional pushed values | 183 // HSimulate::MergeWith() to easily append additional pushed values |
| 184 // that are older (from further down the stack). | 184 // that are older (from further down the stack). |
| 185 for (int i = 0; i < push_count; ++i) { | 185 for (int i = 0; i < push_count; ++i) { |
| 186 instr->AddPushedValue(environment->ExpressionStackAt(i)); | 186 instr->AddPushedValue(environment->ExpressionStackAt(i)); |
| 187 } | 187 } |
| 188 for (GrowableBitVector::Iterator it(environment->assigned_variables(), | 188 for (GrowableBitVector::Iterator it(environment->assigned_variables(), |
| 189 zone()); | 189 zone()); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 | 455 |
| 456 int HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { | 456 int HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { |
| 457 for (int i = 0; i < predecessors_.length(); ++i) { | 457 for (int i = 0; i < predecessors_.length(); ++i) { |
| 458 if (predecessors_[i] == predecessor) return i; | 458 if (predecessors_[i] == predecessor) return i; |
| 459 } | 459 } |
| 460 UNREACHABLE(); | 460 UNREACHABLE(); |
| 461 return -1; | 461 return -1; |
| 462 } | 462 } |
| 463 | 463 |
| 464 | 464 |
| 465 #ifdef DEBUG | 465 #if DCHECK_IS_ON |
| 466 void HBasicBlock::Verify() { | 466 void HBasicBlock::Verify() { |
| 467 // Check that every block is finished. | 467 // Check that every block is finished. |
| 468 DCHECK(IsFinished()); | 468 DCHECK(IsFinished()); |
| 469 DCHECK(block_id() >= 0); | 469 DCHECK(block_id() >= 0); |
| 470 | 470 |
| 471 // Check that the incoming edges are in edge split form. | 471 // Check that the incoming edges are in edge split form. |
| 472 if (predecessors_.length() > 1) { | 472 if (predecessors_.length() > 1) { |
| 473 for (int i = 0; i < predecessors_.length(); ++i) { | 473 for (int i = 0; i < predecessors_.length(); ++i) { |
| 474 DCHECK(predecessors_[i]->end()->SecondSuccessor() == NULL); | 474 DCHECK(predecessors_[i]->end()->SecondSuccessor() == NULL); |
| 475 } | 475 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 506 } else { | 506 } else { |
| 507 block->set_parent_loop_header(loop_header()); | 507 block->set_parent_loop_header(loop_header()); |
| 508 blocks_.Add(block, block->zone()); | 508 blocks_.Add(block, block->zone()); |
| 509 for (int i = 0; i < block->predecessors()->length(); ++i) { | 509 for (int i = 0; i < block->predecessors()->length(); ++i) { |
| 510 AddBlock(block->predecessors()->at(i)); | 510 AddBlock(block->predecessors()->at(i)); |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 } | 513 } |
| 514 | 514 |
| 515 | 515 |
| 516 #ifdef DEBUG | 516 #if DCHECK_IS_ON |
| 517 | 517 |
| 518 // Checks reachability of the blocks in this graph and stores a bit in | 518 // Checks reachability of the blocks in this graph and stores a bit in |
| 519 // the BitVector "reachable()" for every block that can be reached | 519 // the BitVector "reachable()" for every block that can be reached |
| 520 // from the start block of the graph. If "dont_visit" is non-null, the given | 520 // from the start block of the graph. If "dont_visit" is non-null, the given |
| 521 // block is treated as if it would not be part of the graph. "visited_count()" | 521 // block is treated as if it would not be part of the graph. "visited_count()" |
| 522 // returns the number of reachable blocks. | 522 // returns the number of reachable blocks. |
| 523 class ReachabilityAnalyzer BASE_EMBEDDED { | 523 class ReachabilityAnalyzer BASE_EMBEDDED { |
| 524 public: | 524 public: |
| 525 ReachabilityAnalyzer(HBasicBlock* entry_block, | 525 ReachabilityAnalyzer(HBasicBlock* entry_block, |
| 526 int block_count, | 526 int block_count, |
| (...skipping 3317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3844 HBasicBlock* loop_header_; | 3844 HBasicBlock* loop_header_; |
| 3845 int loop_index; | 3845 int loop_index; |
| 3846 int loop_length; | 3846 int loop_length; |
| 3847 HSuccessorIterator successor_iterator; | 3847 HSuccessorIterator successor_iterator; |
| 3848 }; | 3848 }; |
| 3849 | 3849 |
| 3850 | 3850 |
| 3851 void HGraph::OrderBlocks() { | 3851 void HGraph::OrderBlocks() { |
| 3852 CompilationPhase phase("H_Block ordering", info()); | 3852 CompilationPhase phase("H_Block ordering", info()); |
| 3853 | 3853 |
| 3854 #ifdef DEBUG | 3854 #if DCHECK_IS_ON |
| 3855 // Initially the blocks must not be ordered. | 3855 // Initially the blocks must not be ordered. |
| 3856 for (int i = 0; i < blocks_.length(); ++i) { | 3856 for (int i = 0; i < blocks_.length(); ++i) { |
| 3857 DCHECK(!blocks_[i]->IsOrdered()); | 3857 DCHECK(!blocks_[i]->IsOrdered()); |
| 3858 } | 3858 } |
| 3859 #endif | 3859 #endif |
| 3860 | 3860 |
| 3861 PostorderProcessor* postorder = | 3861 PostorderProcessor* postorder = |
| 3862 PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]); | 3862 PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]); |
| 3863 blocks_.Rewind(0); | 3863 blocks_.Rewind(0); |
| 3864 while (postorder) { | 3864 while (postorder) { |
| 3865 postorder = postorder->PerformStep(zone(), &blocks_); | 3865 postorder = postorder->PerformStep(zone(), &blocks_); |
| 3866 } | 3866 } |
| 3867 | 3867 |
| 3868 #ifdef DEBUG | 3868 #if DCHECK_IS_ON |
| 3869 // Now all blocks must be marked as ordered. | 3869 // Now all blocks must be marked as ordered. |
| 3870 for (int i = 0; i < blocks_.length(); ++i) { | 3870 for (int i = 0; i < blocks_.length(); ++i) { |
| 3871 DCHECK(blocks_[i]->IsOrdered()); | 3871 DCHECK(blocks_[i]->IsOrdered()); |
| 3872 } | 3872 } |
| 3873 #endif | 3873 #endif |
| 3874 | 3874 |
| 3875 // Reverse block list and assign block IDs. | 3875 // Reverse block list and assign block IDs. |
| 3876 for (int i = 0, j = blocks_.length(); --j >= i; ++i) { | 3876 for (int i = 0, j = blocks_.length(); --j >= i; ++i) { |
| 3877 HBasicBlock* bi = blocks_[i]; | 3877 HBasicBlock* bi = blocks_[i]; |
| 3878 HBasicBlock* bj = blocks_[j]; | 3878 HBasicBlock* bj = blocks_[j]; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4007 | 4007 |
| 4008 | 4008 |
| 4009 // Implementation of utility classes to represent an expression's context in | 4009 // Implementation of utility classes to represent an expression's context in |
| 4010 // the AST. | 4010 // the AST. |
| 4011 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) | 4011 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
| 4012 : owner_(owner), | 4012 : owner_(owner), |
| 4013 kind_(kind), | 4013 kind_(kind), |
| 4014 outer_(owner->ast_context()), | 4014 outer_(owner->ast_context()), |
| 4015 for_typeof_(false) { | 4015 for_typeof_(false) { |
| 4016 owner->set_ast_context(this); // Push. | 4016 owner->set_ast_context(this); // Push. |
| 4017 #ifdef DEBUG | 4017 #if DCHECK_IS_ON |
| 4018 DCHECK(owner->environment()->frame_type() == JS_FUNCTION); | 4018 DCHECK(owner->environment()->frame_type() == JS_FUNCTION); |
| 4019 original_length_ = owner->environment()->length(); | 4019 original_length_ = owner->environment()->length(); |
| 4020 #endif | 4020 #endif |
| 4021 } | 4021 } |
| 4022 | 4022 |
| 4023 | 4023 |
| 4024 AstContext::~AstContext() { | 4024 AstContext::~AstContext() { |
| 4025 owner_->set_ast_context(outer_); // Pop. | 4025 owner_->set_ast_context(outer_); // Pop. |
| 4026 } | 4026 } |
| 4027 | 4027 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4368 bool HGraph::Optimize(BailoutReason* bailout_reason) { | 4368 bool HGraph::Optimize(BailoutReason* bailout_reason) { |
| 4369 OrderBlocks(); | 4369 OrderBlocks(); |
| 4370 AssignDominators(); | 4370 AssignDominators(); |
| 4371 | 4371 |
| 4372 // We need to create a HConstant "zero" now so that GVN will fold every | 4372 // We need to create a HConstant "zero" now so that GVN will fold every |
| 4373 // zero-valued constant in the graph together. | 4373 // zero-valued constant in the graph together. |
| 4374 // The constant is needed to make idef-based bounds check work: the pass | 4374 // The constant is needed to make idef-based bounds check work: the pass |
| 4375 // evaluates relations with "zero" and that zero cannot be created after GVN. | 4375 // evaluates relations with "zero" and that zero cannot be created after GVN. |
| 4376 GetConstant0(); | 4376 GetConstant0(); |
| 4377 | 4377 |
| 4378 #ifdef DEBUG | 4378 #if DCHECK_IS_ON |
| 4379 // Do a full verify after building the graph and computing dominators. | 4379 // Do a full verify after building the graph and computing dominators. |
| 4380 Verify(true); | 4380 Verify(true); |
| 4381 #endif | 4381 #endif |
| 4382 | 4382 |
| 4383 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { | 4383 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { |
| 4384 Run<HEnvironmentLivenessAnalysisPhase>(); | 4384 Run<HEnvironmentLivenessAnalysisPhase>(); |
| 4385 } | 4385 } |
| 4386 | 4386 |
| 4387 if (!CheckConstPhiUses()) { | 4387 if (!CheckConstPhiUses()) { |
| 4388 *bailout_reason = kUnsupportedPhiUseOfConstVariable; | 4388 *bailout_reason = kUnsupportedPhiUseOfConstVariable; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4453 return true; | 4453 return true; |
| 4454 } | 4454 } |
| 4455 | 4455 |
| 4456 | 4456 |
| 4457 void HGraph::RestoreActualValues() { | 4457 void HGraph::RestoreActualValues() { |
| 4458 HPhase phase("H_Restore actual values", this); | 4458 HPhase phase("H_Restore actual values", this); |
| 4459 | 4459 |
| 4460 for (int block_index = 0; block_index < blocks()->length(); block_index++) { | 4460 for (int block_index = 0; block_index < blocks()->length(); block_index++) { |
| 4461 HBasicBlock* block = blocks()->at(block_index); | 4461 HBasicBlock* block = blocks()->at(block_index); |
| 4462 | 4462 |
| 4463 #ifdef DEBUG | 4463 #if DCHECK_IS_ON |
| 4464 for (int i = 0; i < block->phis()->length(); i++) { | 4464 for (int i = 0; i < block->phis()->length(); i++) { |
| 4465 HPhi* phi = block->phis()->at(i); | 4465 HPhi* phi = block->phis()->at(i); |
| 4466 DCHECK(phi->ActualValue() == phi); | 4466 DCHECK(phi->ActualValue() == phi); |
| 4467 } | 4467 } |
| 4468 #endif | 4468 #endif |
| 4469 | 4469 |
| 4470 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { | 4470 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 4471 HInstruction* instruction = it.Current(); | 4471 HInstruction* instruction = it.Current(); |
| 4472 if (instruction->ActualValue() == instruction) continue; | 4472 if (instruction->ActualValue() == instruction) continue; |
| 4473 if (instruction->CheckFlag(HValue::kIsDead)) { | 4473 if (instruction->CheckFlag(HValue::kIsDead)) { |
| (...skipping 8539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13013 times_.Add(time); | 13013 times_.Add(time); |
| 13014 sizes_.Add(size); | 13014 sizes_.Add(size); |
| 13015 } | 13015 } |
| 13016 | 13016 |
| 13017 | 13017 |
| 13018 HPhase::~HPhase() { | 13018 HPhase::~HPhase() { |
| 13019 if (ShouldProduceTraceOutput()) { | 13019 if (ShouldProduceTraceOutput()) { |
| 13020 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13020 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13021 } | 13021 } |
| 13022 | 13022 |
| 13023 #ifdef DEBUG | 13023 #if DCHECK_IS_ON |
| 13024 graph_->Verify(false); // No full verify. | 13024 graph_->Verify(false); // No full verify. |
| 13025 #endif | 13025 #endif |
| 13026 } | 13026 } |
| 13027 | 13027 |
| 13028 } } // namespace v8::internal | 13028 } } // namespace v8::internal |
| OLD | NEW |