Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 127d7a9aa1ed13943d558e7096ec35ca15ae3818..67efbaf29c14d544df69eb8c36ed25ba00d8fa1f 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -113,11 +113,10 @@ void HBasicBlock::AddInstruction(HInstruction* instr) { |
| ASSERT(!IsStartBlock() || !IsFinished()); |
| ASSERT(!instr->IsLinked()); |
| ASSERT(!IsFinished()); |
| - // Make sure that we never add instructions without knowing |
| - // what the previous ast id is. |
| - ASSERT(instr->IsSimulate() || instr->IsGoto() || |
| - !last_environment()->previous_ast_id().IsNone()); |
| + |
| if (first_ == NULL) { |
| + ASSERT(last_environment() != NULL); |
| + ASSERT(!last_environment()->ast_id().IsNone()); |
| HBlockEntry* entry = new(zone()) HBlockEntry(); |
| entry->InitializeAsFirst(this); |
| first_ = last_ = entry; |
| @@ -215,12 +214,10 @@ void HBasicBlock::AddLeaveInlined(HValue* return_value, |
| } |
| -void HBasicBlock::SetInitialEnvironment(HEnvironment* env, |
| - BailoutId previous_ast_id) { |
| +void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { |
| ASSERT(!HasEnvironment()); |
| ASSERT(first() == NULL); |
| UpdateEnvironment(env); |
| - env->set_previous_ast_id(previous_ast_id); |
| } |
| @@ -236,11 +233,7 @@ void HBasicBlock::SetJoinId(BailoutId ast_id) { |
| predecessor->last_environment()->closure()->shared() |
| ->VerifyBailoutId(ast_id))); |
| simulate->set_ast_id(ast_id); |
| - } |
| - HEnvironment* last_environment = this->last_environment(); |
| - ASSERT(last_environment || IsFinished()); |
| - if (last_environment != NULL) { |
| - last_environment->set_previous_ast_id(ast_id); |
| + predecessor->last_environment()->set_ast_id(ast_id); |
|
danno
2013/04/17 12:04:06
This turns out to be wrong. Please remove this las
titzer
2013/04/17 13:19:16
Tried this, and many tests are now failing with
#
danno
2013/04/17 13:22:51
I must have been confused. I think it is only inco
|
| } |
| } |
| @@ -301,9 +294,7 @@ void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { |
| } |
| } else if (!HasEnvironment() && !IsFinished()) { |
| ASSERT(!IsLoopHeader()); |
| - HEnvironment* new_env = pred->last_environment()->Copy(); |
| - SetInitialEnvironment(new_env, |
| - pred->last_environment()->previous_ast_id()); |
| + SetInitialEnvironment(pred->last_environment()->Copy()); |
| } |
| predecessors_.Add(pred, zone()); |
| @@ -553,6 +544,18 @@ void HGraph::Verify(bool do_full_verify) const { |
| HPhi* phi = block->phis()->at(j); |
| phi->Verify(); |
| } |
| + |
| + // Check that all join blocks have predecessors that end with an |
| + // unconditional goto and agree on their environment node id. |
| + if (block->predecessors()->length() >= 2) { |
| + BailoutId id = |
| + block->predecessors()->first()->last_environment()->ast_id(); |
| + for (int k = 0; k < block->predecessors()->length(); k++) { |
| + HBasicBlock* predecessor = block->predecessors()->at(k); |
| + ASSERT(predecessor->end()->IsGoto()); |
| + ASSERT(predecessor->last_environment()->ast_id() == id); |
| + } |
| + } |
| } |
| // Check special property of first block to have no predecessors. |
| @@ -637,13 +640,13 @@ DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
| #undef DEFINE_GET_CONSTANT |
| -HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) |
| +HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id) |
| : builder_(builder), |
| finished_(false), |
| - id_(builder->current_block()->last_environment()->previous_ast_id()) { |
| + id_(id) { |
| HEnvironment* env = builder->environment(); |
| - failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
| - merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
| + failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); |
| + merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); |
| } |
| @@ -652,9 +655,9 @@ HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { |
| HIsNilAndBranch* compare = |
| new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); |
| HBasicBlock* success_block = |
| - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
| + builder_->CreateBasicBlock(env->CopyWithoutHistory()); |
| HBasicBlock* failure_block = |
| - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
| + builder_->CreateBasicBlock(env->CopyWithoutHistory()); |
| compare->SetSuccessorAt(0, failure_block); |
| compare->SetSuccessorAt(1, success_block); |
| failure_block->Goto(failure_block_); |
| @@ -672,9 +675,9 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, |
| new(zone()) HCompareIDAndBranch(left, right, op); |
| compare->AssumeRepresentation(Representation::Integer32()); |
| HBasicBlock* success_block = |
| - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
| + builder_->CreateBasicBlock(env->CopyWithoutHistory()); |
| HBasicBlock* failure_block = |
| - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
| + builder_->CreateBasicBlock(env->CopyWithoutHistory()); |
| compare->SetSuccessorAt(0, success_block); |
| compare->SetSuccessorAt(1, failure_block); |
| failure_block->Goto(failure_block_); |
| @@ -693,8 +696,8 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, |
| void HGraphBuilder::CheckBuilder::End() { |
| ASSERT(!finished_); |
| builder_->current_block()->Goto(merge_block_); |
| - failure_block_->SetJoinId(id_); |
| failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
| + failure_block_->SetJoinId(id_); |
| builder_->set_current_block(merge_block_); |
| merge_block_->SetJoinId(id_); |
| finished_ = true; |
| @@ -706,15 +709,15 @@ HConstant* HGraph::GetInvalidContext() { |
| } |
| -HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) |
| + HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id) |
| : builder_(builder), |
| finished_(false), |
| did_else_(false), |
| - id_(builder->current_block()->last_environment()->previous_ast_id()) { |
| + id_(id) { |
| HEnvironment* env = builder->environment(); |
| - first_true_block_ = builder->CreateBasicBlock(env->Copy(), id_); |
| + first_true_block_ = builder->CreateBasicBlock(env->Copy()); |
| last_true_block_ = NULL; |
| - first_false_block_ = builder->CreateBasicBlock(env->Copy(), id_); |
| + first_false_block_ = builder->CreateBasicBlock(env->Copy()); |
| } |
| @@ -775,7 +778,7 @@ void HGraphBuilder::IfBuilder::End() { |
| ASSERT(!last_false_block->IsFinished()); |
| HEnvironment* merge_env = |
| last_true_block_->last_environment()->CopyWithoutHistory(); |
| - merge_block_ = builder_->CreateBasicBlock(merge_env, id_); |
| + merge_block_ = builder_->CreateBasicBlock(merge_env); |
| last_true_block_->Goto(merge_block_); |
| last_false_block->Goto(merge_block_); |
| merge_block_->SetJoinId(id_); |
| @@ -786,13 +789,14 @@ void HGraphBuilder::IfBuilder::End() { |
| HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
| HValue* context, |
| - LoopBuilder::Direction direction) |
| + LoopBuilder::Direction direction, |
| + BailoutId id) |
| : builder_(builder), |
| context_(context), |
| direction_(direction), |
| - id_(builder->current_block()->last_environment()->previous_ast_id()), |
| + id_(id), |
| finished_(false) { |
| - header_block_ = builder->CreateLoopHeaderBlock(id_); |
| + header_block_ = builder->CreateLoopHeaderBlock(); |
| body_block_ = NULL; |
| exit_block_ = NULL; |
| } |
| @@ -813,8 +817,8 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody( |
| HEnvironment* body_env = env->Copy(); |
| HEnvironment* exit_env = env->Copy(); |
| - body_block_ = builder_->CreateBasicBlock(body_env, id_); |
| - exit_block_ = builder_->CreateBasicBlock(exit_env, id_); |
| + body_block_ = builder_->CreateBasicBlock(body_env); |
| + exit_block_ = builder_->CreateBasicBlock(exit_env); |
| // Remove the phi from the expression stack |
| body_env->Pop(); |
| @@ -900,7 +904,7 @@ void HGraphBuilder::AddSimulate(BailoutId id, |
| ASSERT(current_block() != NULL); |
| ASSERT(no_side_effects_scope_count_ == 0); |
| current_block()->AddSimulate(id, removable); |
| - environment()->set_previous_ast_id(id); |
| + environment()->set_ast_id(id); |
| } |
| @@ -935,18 +939,17 @@ HReturn* HGraphBuilder::AddReturn(HValue* value) { |
| } |
| -HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env, |
| - BailoutId previous_ast_id) { |
| +HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| HBasicBlock* b = graph()->CreateBasicBlock(); |
| - b->SetInitialEnvironment(env, previous_ast_id); |
| + b->SetInitialEnvironment(env); |
| return b; |
| } |
| -HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock(BailoutId previous_ast_id) { |
| +HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| HBasicBlock* header = graph()->CreateBasicBlock(); |
| HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| - header->SetInitialEnvironment(entry_env, previous_ast_id); |
| + header->SetInitialEnvironment(entry_env); |
| header->AttachLoopInformation(); |
| return header; |
| } |
| @@ -1046,15 +1049,16 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
| HValue* length, |
| HValue* key, |
| bool is_js_array) { |
| + BailoutId ast_id = environment()->ast_id(); |
| Zone* zone = this->zone(); |
| - IfBuilder length_checker(this); |
| + IfBuilder length_checker(this, ast_id); |
| length_checker.BeginIf(length, key, Token::EQ); |
| HValue* current_capacity = |
| AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| - IfBuilder capacity_checker(this); |
| + IfBuilder capacity_checker(this, ast_id); |
| capacity_checker.BeginIf(length, current_capacity, Token::EQ); |
| @@ -1065,7 +1069,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
| HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| kind, length, |
| - new_capacity); |
| + new_capacity, ast_id); |
| environment()->Push(new_elements); |
| capacity_checker.BeginElse(); |
| @@ -1103,10 +1107,11 @@ HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
| HValue* elements, |
| ElementsKind kind, |
| HValue* length) { |
| + BailoutId ast_id = environment()->ast_id(); |
| Zone* zone = this->zone(); |
| Heap* heap = isolate()->heap(); |
| - IfBuilder cow_checker(this); |
| + IfBuilder cow_checker(this, ast_id); |
| cow_checker.BeginIfMapEquals(elements, |
| Handle<Map>(heap->fixed_cow_array_map())); |
| @@ -1116,7 +1121,7 @@ HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
| HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
| kind, length, |
| - capacity); |
| + capacity, ast_id); |
| environment()->Push(new_elements); |
| @@ -1178,9 +1183,11 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| HLoadExternalArrayPointer* external_elements = |
| new(zone) HLoadExternalArrayPointer(elements); |
| AddInstruction(external_elements); |
| - IfBuilder length_checker(this); |
| + BailoutId previous_id = environment()->ast_id(); |
| + ASSERT(!previous_id.IsNone()); |
| + IfBuilder length_checker(this, previous_id); |
| length_checker.BeginIf(key, length, Token::LT); |
| - CheckBuilder negative_checker(this); |
| + CheckBuilder negative_checker(this, previous_id); |
| HValue* bounds_check = negative_checker.CheckIntegerCompare( |
| key, graph()->GetConstant0(), Token::GTE); |
| negative_checker.End(); |
| @@ -1243,7 +1250,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
| ElementsKind kind, |
| - HValue* capacity) { |
| + HValue* capacity, |
| + BailoutId ast_id) { |
| Zone* zone = this->zone(); |
| int elements_size = IsFastDoubleElementsKind(kind) |
| @@ -1307,8 +1315,9 @@ void HGraphBuilder::BuildInitializeElements(HValue* elements, |
| HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
| ElementsKind kind, |
| HValue* capacity) { |
| + BailoutId ast_id = environment()->ast_id(); |
| HValue* new_elements = |
| - BuildAllocateElements(context, kind, capacity); |
| + BuildAllocateElements(context, kind, capacity, ast_id); |
| BuildInitializeElements(new_elements, kind, capacity); |
| return new_elements; |
| } |
| @@ -1385,7 +1394,8 @@ HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
| HValue* elements, |
| ElementsKind kind, |
| HValue* length, |
| - HValue* new_capacity) { |
| + HValue* new_capacity, |
| + BailoutId ast_id) { |
| Zone* zone = this->zone(); |
| HValue* context = environment()->LookupContext(); |
| @@ -1396,7 +1406,7 @@ HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
| BuildCopyElements(context, elements, kind, |
| new_elements, kind, |
| - length, new_capacity); |
| + length, new_capacity, ast_id); |
| Factory* factory = isolate()->factory(); |
| HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
| @@ -1414,7 +1424,8 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
| HValue* elements, |
| ElementsKind elements_kind, |
| HValue* from, |
| - HValue* to) { |
| + HValue* to, |
| + BailoutId ast_id) { |
| // Fast elements kinds need to be initialized in case statements below cause |
| // a garbage collection. |
| Factory* factory = isolate()->factory(); |
| @@ -1427,7 +1438,7 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
| : AddInstruction(new(zone) HConstant(nan_double, |
| Representation::Double())); |
| - LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| + LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); |
| HValue* key = builder.BeginBody(from, to, Token::LT); |
| @@ -1443,7 +1454,8 @@ void HGraphBuilder::BuildCopyElements(HValue* context, |
| HValue* to_elements, |
| ElementsKind to_elements_kind, |
| HValue* length, |
| - HValue* capacity) { |
| + HValue* capacity, |
| + BailoutId ast_id) { |
| bool pre_fill_with_holes = |
| IsFastDoubleElementsKind(from_elements_kind) && |
| IsFastObjectElementsKind(to_elements_kind); |
| @@ -1453,10 +1465,10 @@ void HGraphBuilder::BuildCopyElements(HValue* context, |
| // pre-initialized with holes to make sure that it's always in a consistent |
| // state. |
| BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| - graph()->GetConstant0(), capacity); |
| + graph()->GetConstant0(), capacity, ast_id); |
| } |
| - LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| + LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); |
| HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
| @@ -1473,7 +1485,7 @@ void HGraphBuilder::BuildCopyElements(HValue* context, |
| if (!pre_fill_with_holes && length != capacity) { |
| // Fill unused capacity with the hole. |
| BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| - key, capacity); |
| + key, capacity, ast_id); |
| } |
| } |
| @@ -1684,9 +1696,9 @@ HGraph::HGraph(CompilationInfo* info) |
| start_environment_ = |
| new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| } |
| + start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
| entry_block_ = CreateBasicBlock(); |
| - entry_block_->SetInitialEnvironment(start_environment_, |
| - BailoutId::FunctionEntry()); |
| + entry_block_->SetInitialEnvironment(start_environment_); |
| } |
| @@ -4296,8 +4308,7 @@ bool HOptimizedGraphBuilder::BuildGraph() { |
| // values (but not instructions), present in the initial environment and |
| // not replayed by the Lithium translation. |
| HEnvironment* initial_env = environment()->CopyWithoutHistory(); |
| - HBasicBlock* body_entry = CreateBasicBlock(initial_env, |
| - BailoutId::FunctionEntry()); |
| + HBasicBlock* body_entry = CreateBasicBlock(initial_env); |
| current_block()->Goto(body_entry); |
| body_entry->SetJoinId(BailoutId::FunctionEntry()); |
| set_current_block(body_entry); |
| @@ -5541,7 +5552,7 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| ASSERT(current_block()->HasPredecessor()); |
| ASSERT(current_block() != NULL); |
| bool osr_entry = PreProcessOsrEntry(stmt); |
| - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
| + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| current_block()->Goto(loop_entry); |
| set_current_block(loop_entry); |
| if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| @@ -5584,7 +5595,7 @@ void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
| ASSERT(current_block()->HasPredecessor()); |
| ASSERT(current_block() != NULL); |
| bool osr_entry = PreProcessOsrEntry(stmt); |
| - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
| + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| current_block()->Goto(loop_entry); |
| set_current_block(loop_entry); |
| if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| @@ -5631,7 +5642,7 @@ void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| } |
| ASSERT(current_block() != NULL); |
| bool osr_entry = PreProcessOsrEntry(stmt); |
| - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
| + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| current_block()->Goto(loop_entry); |
| set_current_block(loop_entry); |
| if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| @@ -5726,7 +5737,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
| HForInCacheArray::cast(index_cache)); |
| bool osr_entry = PreProcessOsrEntry(stmt); |
| - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
| + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| current_block()->Goto(loop_entry); |
| set_current_block(loop_entry); |
| if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| @@ -8279,7 +8290,6 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
| AddSimulate(return_id); |
| current_block()->UpdateEnvironment(inner_env); |
| - inner_env->set_previous_ast_id(BailoutId::FunctionEntry()); |
| ZoneList<HValue*>* arguments_values = NULL; |
| // If the function uses arguments copy current arguments values |
| @@ -11033,7 +11043,6 @@ HEnvironment::HEnvironment(HEnvironment* outer, |
| pop_count_(0), |
| push_count_(0), |
| ast_id_(BailoutId::None()), |
| - previous_ast_id_(BailoutId::None()), |
| zone_(zone) { |
| Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
| } |
| @@ -11050,7 +11059,6 @@ HEnvironment::HEnvironment(Zone* zone, int parameter_count) |
| pop_count_(0), |
| push_count_(0), |
| ast_id_(BailoutId::None()), |
| - previous_ast_id_(BailoutId::None()), |
| zone_(zone) { |
| Initialize(parameter_count, 0, 0); |
| } |
| @@ -11067,7 +11075,6 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
| pop_count_(0), |
| push_count_(0), |
| ast_id_(other->ast_id()), |
| - previous_ast_id_(BailoutId::None()), |
| zone_(zone) { |
| Initialize(other); |
| } |
| @@ -11088,7 +11095,6 @@ HEnvironment::HEnvironment(HEnvironment* outer, |
| pop_count_(0), |
| push_count_(0), |
| ast_id_(BailoutId::None()), |
| - previous_ast_id_(BailoutId::None()), |
| zone_(zone) { |
| } |