Chromium Code Reviews| 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 "hydrogen.h" | 5 #include "hydrogen.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "v8.h" | 9 #include "v8.h" |
| 10 #include "allocation-site-scopes.h" | 10 #include "allocation-site-scopes.h" |
| (...skipping 4235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4246 CHECK_ALIVE(Visit(stmt)); | 4246 CHECK_ALIVE(Visit(stmt)); |
| 4247 if (stmt->IsJump()) break; | 4247 if (stmt->IsJump()) break; |
| 4248 } | 4248 } |
| 4249 } | 4249 } |
| 4250 | 4250 |
| 4251 | 4251 |
| 4252 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { | 4252 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
| 4253 ASSERT(!HasStackOverflow()); | 4253 ASSERT(!HasStackOverflow()); |
| 4254 ASSERT(current_block() != NULL); | 4254 ASSERT(current_block() != NULL); |
| 4255 ASSERT(current_block()->HasPredecessor()); | 4255 ASSERT(current_block()->HasPredecessor()); |
| 4256 if (stmt->scope() != NULL) { | 4256 |
| 4257 return Bailout(kScopedBlock); | 4257 Scope* outer_scope = scope(); |
| 4258 Scope* scope = stmt->scope(); | |
| 4259 BreakAndContinueInfo break_info(stmt, outer_scope); | |
| 4260 | |
| 4261 { BreakAndContinueScope push(&break_info, this); | |
| 4262 if (scope != NULL) { | |
| 4263 // Load the function object. | |
| 4264 Scope* declaration_scope = scope->DeclarationScope(); | |
| 4265 HInstruction* function; | |
| 4266 | |
| 4267 HValue* outer_context = environment()->context(); | |
| 4268 if (declaration_scope->is_global_scope() || | |
| 4269 declaration_scope->is_eval_scope()) { | |
| 4270 function = new(zone()) HLoadContextSlot( | |
| 4271 outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck); | |
| 4272 } else { | |
| 4273 function = New<HThisFunction>(); | |
| 4274 } | |
| 4275 AddInstruction(function); | |
| 4276 // Allocate a block context and store it to the stack frame. | |
| 4277 HInstruction* inner_context = Add<HAllocateBlockContext>( | |
| 4278 outer_context, function, scope->GetScopeInfo()); | |
| 4279 HInstruction* instr = Add<HStoreFrameContext>(inner_context); | |
| 4280 if (instr->HasObservableSideEffects()) { | |
| 4281 AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE); | |
| 4282 } | |
| 4283 set_scope(scope); | |
|
rossberg
2014/06/04 12:54:53
Hm, can pushing/popping the scope perhaps be facto
ulan
2014/06/04 14:02:05
Done.
| |
| 4284 environment()->BindContext(inner_context); | |
| 4285 VisitDeclarations(scope->declarations()); | |
| 4286 AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); | |
| 4287 } | |
| 4288 CHECK_BAILOUT(VisitStatements(stmt->statements())); | |
| 4258 } | 4289 } |
| 4259 BreakAndContinueInfo break_info(stmt); | 4290 set_scope(outer_scope); |
| 4260 { BreakAndContinueScope push(&break_info, this); | 4291 if (scope != NULL && current_block() != NULL) { |
| 4261 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4292 HValue* inner_context = environment()->context(); |
| 4293 HValue* outer_context = Add<HLoadNamedField>( | |
| 4294 inner_context, static_cast<HValue*>(NULL), | |
| 4295 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | |
| 4296 | |
| 4297 HInstruction* instr = Add<HStoreFrameContext>(outer_context); | |
| 4298 if (instr->HasObservableSideEffects()) { | |
| 4299 AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE); | |
| 4300 } | |
| 4301 environment()->BindContext(outer_context); | |
| 4262 } | 4302 } |
| 4263 HBasicBlock* break_block = break_info.break_block(); | 4303 HBasicBlock* break_block = break_info.break_block(); |
| 4264 if (break_block != NULL) { | 4304 if (break_block != NULL) { |
| 4265 if (current_block() != NULL) Goto(break_block); | 4305 if (current_block() != NULL) Goto(break_block); |
| 4266 break_block->SetJoinId(stmt->ExitId()); | 4306 break_block->SetJoinId(stmt->ExitId()); |
| 4267 set_current_block(break_block); | 4307 set_current_block(break_block); |
| 4268 } | 4308 } |
| 4269 } | 4309 } |
| 4270 | 4310 |
| 4271 | 4311 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4320 | 4360 |
| 4321 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); | 4361 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); |
| 4322 set_current_block(join); | 4362 set_current_block(join); |
| 4323 } | 4363 } |
| 4324 } | 4364 } |
| 4325 | 4365 |
| 4326 | 4366 |
| 4327 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( | 4367 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( |
| 4328 BreakableStatement* stmt, | 4368 BreakableStatement* stmt, |
| 4329 BreakType type, | 4369 BreakType type, |
| 4370 Scope** scope, | |
| 4330 int* drop_extra) { | 4371 int* drop_extra) { |
| 4331 *drop_extra = 0; | 4372 *drop_extra = 0; |
| 4332 BreakAndContinueScope* current = this; | 4373 BreakAndContinueScope* current = this; |
| 4333 while (current != NULL && current->info()->target() != stmt) { | 4374 while (current != NULL && current->info()->target() != stmt) { |
| 4334 *drop_extra += current->info()->drop_extra(); | 4375 *drop_extra += current->info()->drop_extra(); |
| 4335 current = current->next(); | 4376 current = current->next(); |
| 4336 } | 4377 } |
| 4337 ASSERT(current != NULL); // Always found (unless stack is malformed). | 4378 ASSERT(current != NULL); // Always found (unless stack is malformed). |
| 4379 *scope = current->info()->scope(); | |
| 4338 | 4380 |
| 4339 if (type == BREAK) { | 4381 if (type == BREAK) { |
| 4340 *drop_extra += current->info()->drop_extra(); | 4382 *drop_extra += current->info()->drop_extra(); |
| 4341 } | 4383 } |
| 4342 | 4384 |
| 4343 HBasicBlock* block = NULL; | 4385 HBasicBlock* block = NULL; |
| 4344 switch (type) { | 4386 switch (type) { |
| 4345 case BREAK: | 4387 case BREAK: |
| 4346 block = current->info()->break_block(); | 4388 block = current->info()->break_block(); |
| 4347 if (block == NULL) { | 4389 if (block == NULL) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 4361 | 4403 |
| 4362 return block; | 4404 return block; |
| 4363 } | 4405 } |
| 4364 | 4406 |
| 4365 | 4407 |
| 4366 void HOptimizedGraphBuilder::VisitContinueStatement( | 4408 void HOptimizedGraphBuilder::VisitContinueStatement( |
| 4367 ContinueStatement* stmt) { | 4409 ContinueStatement* stmt) { |
| 4368 ASSERT(!HasStackOverflow()); | 4410 ASSERT(!HasStackOverflow()); |
| 4369 ASSERT(current_block() != NULL); | 4411 ASSERT(current_block() != NULL); |
| 4370 ASSERT(current_block()->HasPredecessor()); | 4412 ASSERT(current_block()->HasPredecessor()); |
| 4413 Scope* outer_scope = NULL; | |
| 4414 Scope* inner_scope = scope(); | |
| 4371 int drop_extra = 0; | 4415 int drop_extra = 0; |
| 4372 HBasicBlock* continue_block = break_scope()->Get( | 4416 HBasicBlock* continue_block = break_scope()->Get( |
| 4373 stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra); | 4417 stmt->target(), BreakAndContinueScope::CONTINUE, |
| 4418 &outer_scope, &drop_extra); | |
| 4419 HValue* context = environment()->context(); | |
| 4374 Drop(drop_extra); | 4420 Drop(drop_extra); |
| 4421 int context_pop_count = inner_scope->ContextChainLength(outer_scope); | |
| 4422 if (context_pop_count > 0) { | |
| 4423 while (context_pop_count-- > 0) { | |
| 4424 HInstruction* context_instruction = Add<HLoadNamedField>( | |
| 4425 context, static_cast<HValue*>(NULL), | |
| 4426 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | |
| 4427 context = context_instruction; | |
| 4428 } | |
| 4429 HInstruction* instr = Add<HStoreFrameContext>(context); | |
| 4430 if (instr->HasObservableSideEffects()) { | |
| 4431 AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); | |
| 4432 } | |
| 4433 environment()->BindContext(context); | |
| 4434 } | |
| 4435 | |
| 4375 Goto(continue_block); | 4436 Goto(continue_block); |
| 4376 set_current_block(NULL); | 4437 set_current_block(NULL); |
| 4377 } | 4438 } |
| 4378 | 4439 |
| 4379 | 4440 |
| 4380 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { | 4441 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { |
| 4381 ASSERT(!HasStackOverflow()); | 4442 ASSERT(!HasStackOverflow()); |
| 4382 ASSERT(current_block() != NULL); | 4443 ASSERT(current_block() != NULL); |
| 4383 ASSERT(current_block()->HasPredecessor()); | 4444 ASSERT(current_block()->HasPredecessor()); |
| 4445 Scope* outer_scope = NULL; | |
| 4446 Scope* inner_scope = scope(); | |
| 4384 int drop_extra = 0; | 4447 int drop_extra = 0; |
| 4385 HBasicBlock* break_block = break_scope()->Get( | 4448 HBasicBlock* break_block = break_scope()->Get( |
| 4386 stmt->target(), BreakAndContinueScope::BREAK, &drop_extra); | 4449 stmt->target(), BreakAndContinueScope::BREAK, |
| 4450 &outer_scope, &drop_extra); | |
| 4451 HValue* context = environment()->context(); | |
| 4387 Drop(drop_extra); | 4452 Drop(drop_extra); |
| 4453 int context_pop_count = inner_scope->ContextChainLength(outer_scope); | |
| 4454 if (context_pop_count > 0) { | |
| 4455 while (context_pop_count-- > 0) { | |
| 4456 HInstruction* context_instruction = Add<HLoadNamedField>( | |
| 4457 context, static_cast<HValue*>(NULL), | |
| 4458 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | |
| 4459 context = context_instruction; | |
| 4460 } | |
| 4461 HInstruction* instr = Add<HStoreFrameContext>(context); | |
| 4462 if (instr->HasObservableSideEffects()) { | |
| 4463 AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); | |
| 4464 } | |
| 4465 environment()->BindContext(context); | |
| 4466 } | |
| 4388 Goto(break_block); | 4467 Goto(break_block); |
| 4389 set_current_block(NULL); | 4468 set_current_block(NULL); |
| 4390 } | 4469 } |
| 4391 | 4470 |
| 4392 | 4471 |
| 4393 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 4472 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
| 4394 ASSERT(!HasStackOverflow()); | 4473 ASSERT(!HasStackOverflow()); |
| 4395 ASSERT(current_block() != NULL); | 4474 ASSERT(current_block() != NULL); |
| 4396 ASSERT(current_block()->HasPredecessor()); | 4475 ASSERT(current_block()->HasPredecessor()); |
| 4397 FunctionState* state = function_state(); | 4476 FunctionState* state = function_state(); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4532 | 4611 |
| 4533 // Save the current block to use for the default or to join with the | 4612 // Save the current block to use for the default or to join with the |
| 4534 // exit. | 4613 // exit. |
| 4535 HBasicBlock* last_block = current_block(); | 4614 HBasicBlock* last_block = current_block(); |
| 4536 Drop(1); // tag_value | 4615 Drop(1); // tag_value |
| 4537 | 4616 |
| 4538 // 2. Loop over the clauses and the linked list of tests in lockstep, | 4617 // 2. Loop over the clauses and the linked list of tests in lockstep, |
| 4539 // translating the clause bodies. | 4618 // translating the clause bodies. |
| 4540 HBasicBlock* fall_through_block = NULL; | 4619 HBasicBlock* fall_through_block = NULL; |
| 4541 | 4620 |
| 4542 BreakAndContinueInfo break_info(stmt); | 4621 BreakAndContinueInfo break_info(stmt, scope()); |
| 4543 { BreakAndContinueScope push(&break_info, this); | 4622 { BreakAndContinueScope push(&break_info, this); |
| 4544 for (int i = 0; i < clause_count; ++i) { | 4623 for (int i = 0; i < clause_count; ++i) { |
| 4545 CaseClause* clause = clauses->at(i); | 4624 CaseClause* clause = clauses->at(i); |
| 4546 | 4625 |
| 4547 // Identify the block where normal (non-fall-through) control flow | 4626 // Identify the block where normal (non-fall-through) control flow |
| 4548 // goes to. | 4627 // goes to. |
| 4549 HBasicBlock* normal_block = NULL; | 4628 HBasicBlock* normal_block = NULL; |
| 4550 if (clause->is_default()) { | 4629 if (clause->is_default()) { |
| 4551 if (last_block == NULL) continue; | 4630 if (last_block == NULL) continue; |
| 4552 normal_block = last_block; | 4631 normal_block = last_block; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 4579 } else { | 4658 } else { |
| 4580 if (fall_through_block != NULL) Goto(fall_through_block, break_block); | 4659 if (fall_through_block != NULL) Goto(fall_through_block, break_block); |
| 4581 if (last_block != NULL) Goto(last_block, break_block); | 4660 if (last_block != NULL) Goto(last_block, break_block); |
| 4582 break_block->SetJoinId(stmt->ExitId()); | 4661 break_block->SetJoinId(stmt->ExitId()); |
| 4583 set_current_block(break_block); | 4662 set_current_block(break_block); |
| 4584 } | 4663 } |
| 4585 } | 4664 } |
| 4586 | 4665 |
| 4587 | 4666 |
| 4588 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 4667 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
| 4589 HBasicBlock* loop_entry, | 4668 HBasicBlock* loop_entry) { |
| 4590 BreakAndContinueInfo* break_info) { | |
| 4591 BreakAndContinueScope push(break_info, this); | |
| 4592 Add<HSimulate>(stmt->StackCheckId()); | 4669 Add<HSimulate>(stmt->StackCheckId()); |
| 4593 HStackCheck* stack_check = | 4670 HStackCheck* stack_check = |
| 4594 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); | 4671 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); |
| 4595 ASSERT(loop_entry->IsLoopHeader()); | 4672 ASSERT(loop_entry->IsLoopHeader()); |
| 4596 loop_entry->loop_information()->set_stack_check(stack_check); | 4673 loop_entry->loop_information()->set_stack_check(stack_check); |
| 4597 CHECK_BAILOUT(Visit(stmt->body())); | 4674 CHECK_BAILOUT(Visit(stmt->body())); |
| 4598 } | 4675 } |
| 4599 | 4676 |
| 4600 | 4677 |
| 4601 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 4678 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 4602 ASSERT(!HasStackOverflow()); | 4679 ASSERT(!HasStackOverflow()); |
| 4603 ASSERT(current_block() != NULL); | 4680 ASSERT(current_block() != NULL); |
| 4604 ASSERT(current_block()->HasPredecessor()); | 4681 ASSERT(current_block()->HasPredecessor()); |
| 4605 ASSERT(current_block() != NULL); | 4682 ASSERT(current_block() != NULL); |
| 4606 HBasicBlock* loop_entry = BuildLoopEntry(stmt); | 4683 HBasicBlock* loop_entry = BuildLoopEntry(stmt); |
| 4607 | 4684 |
| 4608 BreakAndContinueInfo break_info(stmt); | 4685 BreakAndContinueInfo break_info(stmt, scope()); |
| 4609 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4686 { |
| 4687 BreakAndContinueScope push(&break_info, this); | |
| 4688 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); | |
| 4689 } | |
| 4610 HBasicBlock* body_exit = | 4690 HBasicBlock* body_exit = |
| 4611 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4691 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 4612 HBasicBlock* loop_successor = NULL; | 4692 HBasicBlock* loop_successor = NULL; |
| 4613 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { | 4693 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
| 4614 set_current_block(body_exit); | 4694 set_current_block(body_exit); |
| 4615 loop_successor = graph()->CreateBasicBlock(); | 4695 loop_successor = graph()->CreateBasicBlock(); |
| 4616 if (stmt->cond()->ToBooleanIsFalse()) { | 4696 if (stmt->cond()->ToBooleanIsFalse()) { |
| 4617 loop_entry->loop_information()->stack_check()->Eliminate(); | 4697 loop_entry->loop_information()->stack_check()->Eliminate(); |
| 4618 Goto(loop_successor); | 4698 Goto(loop_successor); |
| 4619 body_exit = NULL; | 4699 body_exit = NULL; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4660 body_entry->SetJoinId(stmt->BodyId()); | 4740 body_entry->SetJoinId(stmt->BodyId()); |
| 4661 set_current_block(body_entry); | 4741 set_current_block(body_entry); |
| 4662 } | 4742 } |
| 4663 if (loop_successor->HasPredecessor()) { | 4743 if (loop_successor->HasPredecessor()) { |
| 4664 loop_successor->SetJoinId(stmt->ExitId()); | 4744 loop_successor->SetJoinId(stmt->ExitId()); |
| 4665 } else { | 4745 } else { |
| 4666 loop_successor = NULL; | 4746 loop_successor = NULL; |
| 4667 } | 4747 } |
| 4668 } | 4748 } |
| 4669 | 4749 |
| 4670 BreakAndContinueInfo break_info(stmt); | 4750 BreakAndContinueInfo break_info(stmt, scope()); |
| 4671 if (current_block() != NULL) { | 4751 if (current_block() != NULL) { |
| 4672 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4752 BreakAndContinueScope push(&break_info, this); |
| 4753 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); | |
| 4673 } | 4754 } |
| 4674 HBasicBlock* body_exit = | 4755 HBasicBlock* body_exit = |
| 4675 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4756 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 4676 HBasicBlock* loop_exit = CreateLoop(stmt, | 4757 HBasicBlock* loop_exit = CreateLoop(stmt, |
| 4677 loop_entry, | 4758 loop_entry, |
| 4678 body_exit, | 4759 body_exit, |
| 4679 loop_successor, | 4760 loop_successor, |
| 4680 break_info.break_block()); | 4761 break_info.break_block()); |
| 4681 set_current_block(loop_exit); | 4762 set_current_block(loop_exit); |
| 4682 } | 4763 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 4701 body_entry->SetJoinId(stmt->BodyId()); | 4782 body_entry->SetJoinId(stmt->BodyId()); |
| 4702 set_current_block(body_entry); | 4783 set_current_block(body_entry); |
| 4703 } | 4784 } |
| 4704 if (loop_successor->HasPredecessor()) { | 4785 if (loop_successor->HasPredecessor()) { |
| 4705 loop_successor->SetJoinId(stmt->ExitId()); | 4786 loop_successor->SetJoinId(stmt->ExitId()); |
| 4706 } else { | 4787 } else { |
| 4707 loop_successor = NULL; | 4788 loop_successor = NULL; |
| 4708 } | 4789 } |
| 4709 } | 4790 } |
| 4710 | 4791 |
| 4711 BreakAndContinueInfo break_info(stmt); | 4792 BreakAndContinueInfo break_info(stmt, scope()); |
| 4712 if (current_block() != NULL) { | 4793 if (current_block() != NULL) { |
| 4713 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4794 BreakAndContinueScope push(&break_info, this); |
| 4795 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); | |
| 4714 } | 4796 } |
| 4715 HBasicBlock* body_exit = | 4797 HBasicBlock* body_exit = |
| 4716 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4798 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 4717 | 4799 |
| 4718 if (stmt->next() != NULL && body_exit != NULL) { | 4800 if (stmt->next() != NULL && body_exit != NULL) { |
| 4719 set_current_block(body_exit); | 4801 set_current_block(body_exit); |
| 4720 CHECK_BAILOUT(Visit(stmt->next())); | 4802 CHECK_BAILOUT(Visit(stmt->next())); |
| 4721 body_exit = current_block(); | 4803 body_exit = current_block(); |
| 4722 } | 4804 } |
| 4723 | 4805 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4802 environment()->ExpressionStackAt(0), | 4884 environment()->ExpressionStackAt(0), |
| 4803 FAST_ELEMENTS); | 4885 FAST_ELEMENTS); |
| 4804 | 4886 |
| 4805 // Check if the expected map still matches that of the enumerable. | 4887 // Check if the expected map still matches that of the enumerable. |
| 4806 // If not just deoptimize. | 4888 // If not just deoptimize. |
| 4807 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), | 4889 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), |
| 4808 environment()->ExpressionStackAt(3)); | 4890 environment()->ExpressionStackAt(3)); |
| 4809 | 4891 |
| 4810 Bind(each_var, key); | 4892 Bind(each_var, key); |
| 4811 | 4893 |
| 4812 BreakAndContinueInfo break_info(stmt, 5); | 4894 BreakAndContinueInfo break_info(stmt, scope(), 5); |
| 4813 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4895 { |
| 4896 BreakAndContinueScope push(&break_info, this); | |
| 4897 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); | |
| 4898 } | |
| 4814 | 4899 |
| 4815 HBasicBlock* body_exit = | 4900 HBasicBlock* body_exit = |
| 4816 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4901 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 4817 | 4902 |
| 4818 if (body_exit != NULL) { | 4903 if (body_exit != NULL) { |
| 4819 set_current_block(body_exit); | 4904 set_current_block(body_exit); |
| 4820 | 4905 |
| 4821 HValue* current_index = Pop(); | 4906 HValue* current_index = Pop(); |
| 4822 Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1())); | 4907 Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1())); |
| 4823 body_exit = current_block(); | 4908 body_exit = current_block(); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4948 return kUseGeneric; | 5033 return kUseGeneric; |
| 4949 } | 5034 } |
| 4950 | 5035 |
| 4951 return kUseCell; | 5036 return kUseCell; |
| 4952 } | 5037 } |
| 4953 | 5038 |
| 4954 | 5039 |
| 4955 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5040 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
| 4956 ASSERT(var->IsContextSlot()); | 5041 ASSERT(var->IsContextSlot()); |
| 4957 HValue* context = environment()->context(); | 5042 HValue* context = environment()->context(); |
| 4958 int length = current_info()->scope()->ContextChainLength(var->scope()); | 5043 int length = scope()->ContextChainLength(var->scope()); |
| 4959 while (length-- > 0) { | 5044 while (length-- > 0) { |
| 4960 context = Add<HLoadNamedField>( | 5045 context = Add<HLoadNamedField>( |
| 4961 context, static_cast<HValue*>(NULL), | 5046 context, static_cast<HValue*>(NULL), |
| 4962 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 5047 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4963 } | 5048 } |
| 4964 return context; | 5049 return context; |
| 4965 } | 5050 } |
| 4966 | 5051 |
| 4967 | 5052 |
| 4968 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5053 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5032 if (value == graph()->GetConstantHole()) { | 5117 if (value == graph()->GetConstantHole()) { |
| 5033 ASSERT(IsDeclaredVariableMode(variable->mode()) && | 5118 ASSERT(IsDeclaredVariableMode(variable->mode()) && |
| 5034 variable->mode() != VAR); | 5119 variable->mode() != VAR); |
| 5035 return Bailout(kReferenceToUninitializedVariable); | 5120 return Bailout(kReferenceToUninitializedVariable); |
| 5036 } | 5121 } |
| 5037 return ast_context()->ReturnValue(value); | 5122 return ast_context()->ReturnValue(value); |
| 5038 } | 5123 } |
| 5039 | 5124 |
| 5040 case Variable::CONTEXT: { | 5125 case Variable::CONTEXT: { |
| 5041 HValue* context = BuildContextChainWalk(variable); | 5126 HValue* context = BuildContextChainWalk(variable); |
| 5042 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable); | 5127 HLoadContextSlot::Mode mode; |
| 5128 switch (variable->mode()) { | |
| 5129 case LET: | |
| 5130 case CONST: | |
| 5131 mode = HLoadContextSlot::kCheckDeoptimize; | |
| 5132 break; | |
| 5133 case CONST_LEGACY: | |
| 5134 mode = HLoadContextSlot::kCheckReturnUndefined; | |
| 5135 break; | |
| 5136 default: | |
| 5137 mode = HLoadContextSlot::kNoCheck; | |
| 5138 break; | |
| 5139 } | |
| 5140 HLoadContextSlot* instr = | |
| 5141 new(zone()) HLoadContextSlot(context, variable->index(), mode); | |
| 5043 return ast_context()->ReturnInstruction(instr, expr->id()); | 5142 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5044 } | 5143 } |
| 5045 | 5144 |
| 5046 case Variable::LOOKUP: | 5145 case Variable::LOOKUP: |
| 5047 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); | 5146 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); |
| 5048 } | 5147 } |
| 5049 } | 5148 } |
| 5050 | 5149 |
| 5051 | 5150 |
| 5052 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { | 5151 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { |
| (...skipping 2422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7475 } | 7574 } |
| 7476 | 7575 |
| 7477 // Capture the state before invoking the inlined function for deopt in the | 7576 // Capture the state before invoking the inlined function for deopt in the |
| 7478 // inlined function. This simulate has no bailout-id since it's not directly | 7577 // inlined function. This simulate has no bailout-id since it's not directly |
| 7479 // reachable for deopt, and is only used to capture the state. If the simulate | 7578 // reachable for deopt, and is only used to capture the state. If the simulate |
| 7480 // becomes reachable by merging, the ast id of the simulate merged into it is | 7579 // becomes reachable by merging, the ast id of the simulate merged into it is |
| 7481 // adopted. | 7580 // adopted. |
| 7482 Add<HSimulate>(BailoutId::None()); | 7581 Add<HSimulate>(BailoutId::None()); |
| 7483 | 7582 |
| 7484 current_block()->UpdateEnvironment(inner_env); | 7583 current_block()->UpdateEnvironment(inner_env); |
| 7485 | 7584 Scope* saved_scope = scope(); |
| 7585 set_scope(target_info.scope()); | |
| 7486 HEnterInlined* enter_inlined = | 7586 HEnterInlined* enter_inlined = |
| 7487 Add<HEnterInlined>(return_id, target, arguments_count, function, | 7587 Add<HEnterInlined>(return_id, target, arguments_count, function, |
| 7488 function_state()->inlining_kind(), | 7588 function_state()->inlining_kind(), |
| 7489 function->scope()->arguments(), | 7589 function->scope()->arguments(), |
| 7490 arguments_object); | 7590 arguments_object); |
| 7491 function_state()->set_entry(enter_inlined); | 7591 function_state()->set_entry(enter_inlined); |
| 7492 | 7592 |
| 7493 VisitDeclarations(target_info.scope()->declarations()); | 7593 VisitDeclarations(target_info.scope()->declarations()); |
| 7494 VisitStatements(function->body()); | 7594 VisitStatements(function->body()); |
| 7595 set_scope(saved_scope); | |
| 7495 if (HasStackOverflow()) { | 7596 if (HasStackOverflow()) { |
| 7496 // Bail out if the inline function did, as we cannot residualize a call | 7597 // Bail out if the inline function did, as we cannot residualize a call |
| 7497 // instead. | 7598 // instead. |
| 7498 TraceInline(target, caller, "inline graph construction failed"); | 7599 TraceInline(target, caller, "inline graph construction failed"); |
| 7499 target_shared->DisableOptimization(kInliningBailedOut); | 7600 target_shared->DisableOptimization(kInliningBailedOut); |
| 7500 inline_bailout_ = true; | 7601 inline_bailout_ = true; |
| 7501 delete target_state; | 7602 delete target_state; |
| 7502 return true; | 7603 return true; |
| 7503 } | 7604 } |
| 7504 | 7605 |
| (...skipping 3677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11182 frame_type_(JS_FUNCTION), | 11283 frame_type_(JS_FUNCTION), |
| 11183 parameter_count_(0), | 11284 parameter_count_(0), |
| 11184 specials_count_(1), | 11285 specials_count_(1), |
| 11185 local_count_(0), | 11286 local_count_(0), |
| 11186 outer_(outer), | 11287 outer_(outer), |
| 11187 entry_(NULL), | 11288 entry_(NULL), |
| 11188 pop_count_(0), | 11289 pop_count_(0), |
| 11189 push_count_(0), | 11290 push_count_(0), |
| 11190 ast_id_(BailoutId::None()), | 11291 ast_id_(BailoutId::None()), |
| 11191 zone_(zone) { | 11292 zone_(zone) { |
| 11192 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 11293 Scope* declaration_scope = scope->DeclarationScope(); |
| 11294 Initialize(declaration_scope->num_parameters() + 1, | |
| 11295 declaration_scope->num_stack_slots(), 0); | |
| 11193 } | 11296 } |
| 11194 | 11297 |
| 11195 | 11298 |
| 11196 HEnvironment::HEnvironment(Zone* zone, int parameter_count) | 11299 HEnvironment::HEnvironment(Zone* zone, int parameter_count) |
| 11197 : values_(0, zone), | 11300 : values_(0, zone), |
| 11198 frame_type_(STUB), | 11301 frame_type_(STUB), |
| 11199 parameter_count_(parameter_count), | 11302 parameter_count_(parameter_count), |
| 11200 specials_count_(1), | 11303 specials_count_(1), |
| 11201 local_count_(0), | 11304 local_count_(0), |
| 11202 outer_(NULL), | 11305 outer_(NULL), |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11795 if (ShouldProduceTraceOutput()) { | 11898 if (ShouldProduceTraceOutput()) { |
| 11796 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11899 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11797 } | 11900 } |
| 11798 | 11901 |
| 11799 #ifdef DEBUG | 11902 #ifdef DEBUG |
| 11800 graph_->Verify(false); // No full verify. | 11903 graph_->Verify(false); // No full verify. |
| 11801 #endif | 11904 #endif |
| 11802 } | 11905 } |
| 11803 | 11906 |
| 11804 } } // namespace v8::internal | 11907 } } // namespace v8::internal |
| OLD | NEW |