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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 4229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4240 CHECK_ALIVE(Visit(stmt)); | 4240 CHECK_ALIVE(Visit(stmt)); |
4241 if (stmt->IsJump()) break; | 4241 if (stmt->IsJump()) break; |
4242 } | 4242 } |
4243 } | 4243 } |
4244 | 4244 |
4245 | 4245 |
4246 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { | 4246 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
4247 ASSERT(!HasStackOverflow()); | 4247 ASSERT(!HasStackOverflow()); |
4248 ASSERT(current_block() != NULL); | 4248 ASSERT(current_block() != NULL); |
4249 ASSERT(current_block()->HasPredecessor()); | 4249 ASSERT(current_block()->HasPredecessor()); |
4250 if (stmt->scope() != NULL) { | 4250 |
4251 return Bailout(kScopedBlock); | 4251 Scope* outer_scope = scope(); |
| 4252 Scope* scope = stmt->scope(); |
| 4253 BreakAndContinueInfo break_info(stmt, outer_scope); |
| 4254 |
| 4255 { BreakAndContinueScope push(&break_info, this); |
| 4256 if (scope != NULL) { |
| 4257 // Load the function object. |
| 4258 Scope* declaration_scope = scope->DeclarationScope(); |
| 4259 HInstruction* function; |
| 4260 HValue* outer_context = environment()->context(); |
| 4261 if (declaration_scope->is_global_scope() || |
| 4262 declaration_scope->is_eval_scope()) { |
| 4263 function = new(zone()) HLoadContextSlot( |
| 4264 outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck); |
| 4265 } else { |
| 4266 function = New<HThisFunction>(); |
| 4267 } |
| 4268 AddInstruction(function); |
| 4269 // Allocate a block context and store it to the stack frame. |
| 4270 HInstruction* inner_context = Add<HAllocateBlockContext>( |
| 4271 outer_context, function, scope->GetScopeInfo()); |
| 4272 HInstruction* instr = Add<HStoreFrameContext>(inner_context); |
| 4273 if (instr->HasObservableSideEffects()) { |
| 4274 AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE); |
| 4275 } |
| 4276 set_scope(scope); |
| 4277 environment()->BindContext(inner_context); |
| 4278 VisitDeclarations(scope->declarations()); |
| 4279 AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); |
| 4280 } |
| 4281 CHECK_BAILOUT(VisitStatements(stmt->statements())); |
4252 } | 4282 } |
4253 BreakAndContinueInfo break_info(stmt); | 4283 set_scope(outer_scope); |
4254 { BreakAndContinueScope push(&break_info, this); | 4284 if (scope != NULL && current_block() != NULL) { |
4255 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4285 HValue* inner_context = environment()->context(); |
| 4286 HValue* outer_context = Add<HLoadNamedField>( |
| 4287 inner_context, static_cast<HValue*>(NULL), |
| 4288 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4289 |
| 4290 HInstruction* instr = Add<HStoreFrameContext>(outer_context); |
| 4291 if (instr->HasObservableSideEffects()) { |
| 4292 AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE); |
| 4293 } |
| 4294 environment()->BindContext(outer_context); |
4256 } | 4295 } |
4257 HBasicBlock* break_block = break_info.break_block(); | 4296 HBasicBlock* break_block = break_info.break_block(); |
4258 if (break_block != NULL) { | 4297 if (break_block != NULL) { |
4259 if (current_block() != NULL) Goto(break_block); | 4298 if (current_block() != NULL) Goto(break_block); |
4260 break_block->SetJoinId(stmt->ExitId()); | 4299 break_block->SetJoinId(stmt->ExitId()); |
4261 set_current_block(break_block); | 4300 set_current_block(break_block); |
4262 } | 4301 } |
4263 } | 4302 } |
4264 | 4303 |
4265 | 4304 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4314 | 4353 |
4315 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); | 4354 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); |
4316 set_current_block(join); | 4355 set_current_block(join); |
4317 } | 4356 } |
4318 } | 4357 } |
4319 | 4358 |
4320 | 4359 |
4321 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( | 4360 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( |
4322 BreakableStatement* stmt, | 4361 BreakableStatement* stmt, |
4323 BreakType type, | 4362 BreakType type, |
| 4363 Scope** scope, |
4324 int* drop_extra) { | 4364 int* drop_extra) { |
4325 *drop_extra = 0; | 4365 *drop_extra = 0; |
4326 BreakAndContinueScope* current = this; | 4366 BreakAndContinueScope* current = this; |
4327 while (current != NULL && current->info()->target() != stmt) { | 4367 while (current != NULL && current->info()->target() != stmt) { |
4328 *drop_extra += current->info()->drop_extra(); | 4368 *drop_extra += current->info()->drop_extra(); |
4329 current = current->next(); | 4369 current = current->next(); |
4330 } | 4370 } |
4331 ASSERT(current != NULL); // Always found (unless stack is malformed). | 4371 ASSERT(current != NULL); // Always found (unless stack is malformed). |
| 4372 *scope = current->info()->scope(); |
4332 | 4373 |
4333 if (type == BREAK) { | 4374 if (type == BREAK) { |
4334 *drop_extra += current->info()->drop_extra(); | 4375 *drop_extra += current->info()->drop_extra(); |
4335 } | 4376 } |
4336 | 4377 |
4337 HBasicBlock* block = NULL; | 4378 HBasicBlock* block = NULL; |
4338 switch (type) { | 4379 switch (type) { |
4339 case BREAK: | 4380 case BREAK: |
4340 block = current->info()->break_block(); | 4381 block = current->info()->break_block(); |
4341 if (block == NULL) { | 4382 if (block == NULL) { |
(...skipping 13 matching lines...) Expand all Loading... |
4355 | 4396 |
4356 return block; | 4397 return block; |
4357 } | 4398 } |
4358 | 4399 |
4359 | 4400 |
4360 void HOptimizedGraphBuilder::VisitContinueStatement( | 4401 void HOptimizedGraphBuilder::VisitContinueStatement( |
4361 ContinueStatement* stmt) { | 4402 ContinueStatement* stmt) { |
4362 ASSERT(!HasStackOverflow()); | 4403 ASSERT(!HasStackOverflow()); |
4363 ASSERT(current_block() != NULL); | 4404 ASSERT(current_block() != NULL); |
4364 ASSERT(current_block()->HasPredecessor()); | 4405 ASSERT(current_block()->HasPredecessor()); |
| 4406 Scope* outer_scope = NULL; |
| 4407 Scope* inner_scope = scope(); |
4365 int drop_extra = 0; | 4408 int drop_extra = 0; |
4366 HBasicBlock* continue_block = break_scope()->Get( | 4409 HBasicBlock* continue_block = break_scope()->Get( |
4367 stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra); | 4410 stmt->target(), BreakAndContinueScope::CONTINUE, |
| 4411 &outer_scope, &drop_extra); |
| 4412 HValue* context = environment()->context(); |
4368 Drop(drop_extra); | 4413 Drop(drop_extra); |
| 4414 int context_pop_count = inner_scope->ContextChainLength(outer_scope); |
| 4415 if (context_pop_count > 0) { |
| 4416 while (context_pop_count-- > 0) { |
| 4417 HInstruction* context_instruction = Add<HLoadNamedField>( |
| 4418 context, static_cast<HValue*>(NULL), |
| 4419 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4420 context = context_instruction; |
| 4421 } |
| 4422 HInstruction* instr = Add<HStoreFrameContext>(context); |
| 4423 if (instr->HasObservableSideEffects()) { |
| 4424 AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); |
| 4425 } |
| 4426 environment()->BindContext(context); |
| 4427 } |
| 4428 |
4369 Goto(continue_block); | 4429 Goto(continue_block); |
4370 set_current_block(NULL); | 4430 set_current_block(NULL); |
4371 } | 4431 } |
4372 | 4432 |
4373 | 4433 |
4374 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { | 4434 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { |
4375 ASSERT(!HasStackOverflow()); | 4435 ASSERT(!HasStackOverflow()); |
4376 ASSERT(current_block() != NULL); | 4436 ASSERT(current_block() != NULL); |
4377 ASSERT(current_block()->HasPredecessor()); | 4437 ASSERT(current_block()->HasPredecessor()); |
| 4438 Scope* outer_scope = NULL; |
| 4439 Scope* inner_scope = scope(); |
4378 int drop_extra = 0; | 4440 int drop_extra = 0; |
4379 HBasicBlock* break_block = break_scope()->Get( | 4441 HBasicBlock* break_block = break_scope()->Get( |
4380 stmt->target(), BreakAndContinueScope::BREAK, &drop_extra); | 4442 stmt->target(), BreakAndContinueScope::BREAK, |
| 4443 &outer_scope, &drop_extra); |
| 4444 HValue* context = environment()->context(); |
4381 Drop(drop_extra); | 4445 Drop(drop_extra); |
| 4446 int context_pop_count = inner_scope->ContextChainLength(outer_scope); |
| 4447 if (context_pop_count > 0) { |
| 4448 while (context_pop_count-- > 0) { |
| 4449 HInstruction* context_instruction = Add<HLoadNamedField>( |
| 4450 context, static_cast<HValue*>(NULL), |
| 4451 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4452 context = context_instruction; |
| 4453 } |
| 4454 HInstruction* instr = Add<HStoreFrameContext>(context); |
| 4455 if (instr->HasObservableSideEffects()) { |
| 4456 AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); |
| 4457 } |
| 4458 environment()->BindContext(context); |
| 4459 } |
4382 Goto(break_block); | 4460 Goto(break_block); |
4383 set_current_block(NULL); | 4461 set_current_block(NULL); |
4384 } | 4462 } |
4385 | 4463 |
4386 | 4464 |
4387 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 4465 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
4388 ASSERT(!HasStackOverflow()); | 4466 ASSERT(!HasStackOverflow()); |
4389 ASSERT(current_block() != NULL); | 4467 ASSERT(current_block() != NULL); |
4390 ASSERT(current_block()->HasPredecessor()); | 4468 ASSERT(current_block()->HasPredecessor()); |
4391 FunctionState* state = function_state(); | 4469 FunctionState* state = function_state(); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 | 4604 |
4527 // Save the current block to use for the default or to join with the | 4605 // Save the current block to use for the default or to join with the |
4528 // exit. | 4606 // exit. |
4529 HBasicBlock* last_block = current_block(); | 4607 HBasicBlock* last_block = current_block(); |
4530 Drop(1); // tag_value | 4608 Drop(1); // tag_value |
4531 | 4609 |
4532 // 2. Loop over the clauses and the linked list of tests in lockstep, | 4610 // 2. Loop over the clauses and the linked list of tests in lockstep, |
4533 // translating the clause bodies. | 4611 // translating the clause bodies. |
4534 HBasicBlock* fall_through_block = NULL; | 4612 HBasicBlock* fall_through_block = NULL; |
4535 | 4613 |
4536 BreakAndContinueInfo break_info(stmt); | 4614 BreakAndContinueInfo break_info(stmt, scope()); |
4537 { BreakAndContinueScope push(&break_info, this); | 4615 { BreakAndContinueScope push(&break_info, this); |
4538 for (int i = 0; i < clause_count; ++i) { | 4616 for (int i = 0; i < clause_count; ++i) { |
4539 CaseClause* clause = clauses->at(i); | 4617 CaseClause* clause = clauses->at(i); |
4540 | 4618 |
4541 // Identify the block where normal (non-fall-through) control flow | 4619 // Identify the block where normal (non-fall-through) control flow |
4542 // goes to. | 4620 // goes to. |
4543 HBasicBlock* normal_block = NULL; | 4621 HBasicBlock* normal_block = NULL; |
4544 if (clause->is_default()) { | 4622 if (clause->is_default()) { |
4545 if (last_block == NULL) continue; | 4623 if (last_block == NULL) continue; |
4546 normal_block = last_block; | 4624 normal_block = last_block; |
(...skipping 26 matching lines...) Expand all Loading... |
4573 } else { | 4651 } else { |
4574 if (fall_through_block != NULL) Goto(fall_through_block, break_block); | 4652 if (fall_through_block != NULL) Goto(fall_through_block, break_block); |
4575 if (last_block != NULL) Goto(last_block, break_block); | 4653 if (last_block != NULL) Goto(last_block, break_block); |
4576 break_block->SetJoinId(stmt->ExitId()); | 4654 break_block->SetJoinId(stmt->ExitId()); |
4577 set_current_block(break_block); | 4655 set_current_block(break_block); |
4578 } | 4656 } |
4579 } | 4657 } |
4580 | 4658 |
4581 | 4659 |
4582 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 4660 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
4583 HBasicBlock* loop_entry, | 4661 HBasicBlock* loop_entry) { |
4584 BreakAndContinueInfo* break_info) { | |
4585 BreakAndContinueScope push(break_info, this); | |
4586 Add<HSimulate>(stmt->StackCheckId()); | 4662 Add<HSimulate>(stmt->StackCheckId()); |
4587 HStackCheck* stack_check = | 4663 HStackCheck* stack_check = |
4588 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); | 4664 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); |
4589 ASSERT(loop_entry->IsLoopHeader()); | 4665 ASSERT(loop_entry->IsLoopHeader()); |
4590 loop_entry->loop_information()->set_stack_check(stack_check); | 4666 loop_entry->loop_information()->set_stack_check(stack_check); |
4591 CHECK_BAILOUT(Visit(stmt->body())); | 4667 CHECK_BAILOUT(Visit(stmt->body())); |
4592 } | 4668 } |
4593 | 4669 |
4594 | 4670 |
4595 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 4671 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
4596 ASSERT(!HasStackOverflow()); | 4672 ASSERT(!HasStackOverflow()); |
4597 ASSERT(current_block() != NULL); | 4673 ASSERT(current_block() != NULL); |
4598 ASSERT(current_block()->HasPredecessor()); | 4674 ASSERT(current_block()->HasPredecessor()); |
4599 ASSERT(current_block() != NULL); | 4675 ASSERT(current_block() != NULL); |
4600 HBasicBlock* loop_entry = BuildLoopEntry(stmt); | 4676 HBasicBlock* loop_entry = BuildLoopEntry(stmt); |
4601 | 4677 |
4602 BreakAndContinueInfo break_info(stmt); | 4678 BreakAndContinueInfo break_info(stmt, scope()); |
4603 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4679 { |
| 4680 BreakAndContinueScope push(&break_info, this); |
| 4681 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); |
| 4682 } |
4604 HBasicBlock* body_exit = | 4683 HBasicBlock* body_exit = |
4605 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4684 JoinContinue(stmt, current_block(), break_info.continue_block()); |
4606 HBasicBlock* loop_successor = NULL; | 4685 HBasicBlock* loop_successor = NULL; |
4607 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { | 4686 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
4608 set_current_block(body_exit); | 4687 set_current_block(body_exit); |
4609 loop_successor = graph()->CreateBasicBlock(); | 4688 loop_successor = graph()->CreateBasicBlock(); |
4610 if (stmt->cond()->ToBooleanIsFalse()) { | 4689 if (stmt->cond()->ToBooleanIsFalse()) { |
4611 loop_entry->loop_information()->stack_check()->Eliminate(); | 4690 loop_entry->loop_information()->stack_check()->Eliminate(); |
4612 Goto(loop_successor); | 4691 Goto(loop_successor); |
4613 body_exit = NULL; | 4692 body_exit = NULL; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4654 body_entry->SetJoinId(stmt->BodyId()); | 4733 body_entry->SetJoinId(stmt->BodyId()); |
4655 set_current_block(body_entry); | 4734 set_current_block(body_entry); |
4656 } | 4735 } |
4657 if (loop_successor->HasPredecessor()) { | 4736 if (loop_successor->HasPredecessor()) { |
4658 loop_successor->SetJoinId(stmt->ExitId()); | 4737 loop_successor->SetJoinId(stmt->ExitId()); |
4659 } else { | 4738 } else { |
4660 loop_successor = NULL; | 4739 loop_successor = NULL; |
4661 } | 4740 } |
4662 } | 4741 } |
4663 | 4742 |
4664 BreakAndContinueInfo break_info(stmt); | 4743 BreakAndContinueInfo break_info(stmt, scope()); |
4665 if (current_block() != NULL) { | 4744 if (current_block() != NULL) { |
4666 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4745 BreakAndContinueScope push(&break_info, this); |
| 4746 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); |
4667 } | 4747 } |
4668 HBasicBlock* body_exit = | 4748 HBasicBlock* body_exit = |
4669 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4749 JoinContinue(stmt, current_block(), break_info.continue_block()); |
4670 HBasicBlock* loop_exit = CreateLoop(stmt, | 4750 HBasicBlock* loop_exit = CreateLoop(stmt, |
4671 loop_entry, | 4751 loop_entry, |
4672 body_exit, | 4752 body_exit, |
4673 loop_successor, | 4753 loop_successor, |
4674 break_info.break_block()); | 4754 break_info.break_block()); |
4675 set_current_block(loop_exit); | 4755 set_current_block(loop_exit); |
4676 } | 4756 } |
(...skipping 18 matching lines...) Expand all Loading... |
4695 body_entry->SetJoinId(stmt->BodyId()); | 4775 body_entry->SetJoinId(stmt->BodyId()); |
4696 set_current_block(body_entry); | 4776 set_current_block(body_entry); |
4697 } | 4777 } |
4698 if (loop_successor->HasPredecessor()) { | 4778 if (loop_successor->HasPredecessor()) { |
4699 loop_successor->SetJoinId(stmt->ExitId()); | 4779 loop_successor->SetJoinId(stmt->ExitId()); |
4700 } else { | 4780 } else { |
4701 loop_successor = NULL; | 4781 loop_successor = NULL; |
4702 } | 4782 } |
4703 } | 4783 } |
4704 | 4784 |
4705 BreakAndContinueInfo break_info(stmt); | 4785 BreakAndContinueInfo break_info(stmt, scope()); |
4706 if (current_block() != NULL) { | 4786 if (current_block() != NULL) { |
4707 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4787 BreakAndContinueScope push(&break_info, this); |
| 4788 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); |
4708 } | 4789 } |
4709 HBasicBlock* body_exit = | 4790 HBasicBlock* body_exit = |
4710 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4791 JoinContinue(stmt, current_block(), break_info.continue_block()); |
4711 | 4792 |
4712 if (stmt->next() != NULL && body_exit != NULL) { | 4793 if (stmt->next() != NULL && body_exit != NULL) { |
4713 set_current_block(body_exit); | 4794 set_current_block(body_exit); |
4714 CHECK_BAILOUT(Visit(stmt->next())); | 4795 CHECK_BAILOUT(Visit(stmt->next())); |
4715 body_exit = current_block(); | 4796 body_exit = current_block(); |
4716 } | 4797 } |
4717 | 4798 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4796 environment()->ExpressionStackAt(0), | 4877 environment()->ExpressionStackAt(0), |
4797 FAST_ELEMENTS); | 4878 FAST_ELEMENTS); |
4798 | 4879 |
4799 // Check if the expected map still matches that of the enumerable. | 4880 // Check if the expected map still matches that of the enumerable. |
4800 // If not just deoptimize. | 4881 // If not just deoptimize. |
4801 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), | 4882 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), |
4802 environment()->ExpressionStackAt(3)); | 4883 environment()->ExpressionStackAt(3)); |
4803 | 4884 |
4804 Bind(each_var, key); | 4885 Bind(each_var, key); |
4805 | 4886 |
4806 BreakAndContinueInfo break_info(stmt, 5); | 4887 BreakAndContinueInfo break_info(stmt, scope(), 5); |
4807 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 4888 { |
| 4889 BreakAndContinueScope push(&break_info, this); |
| 4890 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); |
| 4891 } |
4808 | 4892 |
4809 HBasicBlock* body_exit = | 4893 HBasicBlock* body_exit = |
4810 JoinContinue(stmt, current_block(), break_info.continue_block()); | 4894 JoinContinue(stmt, current_block(), break_info.continue_block()); |
4811 | 4895 |
4812 if (body_exit != NULL) { | 4896 if (body_exit != NULL) { |
4813 set_current_block(body_exit); | 4897 set_current_block(body_exit); |
4814 | 4898 |
4815 HValue* current_index = Pop(); | 4899 HValue* current_index = Pop(); |
4816 Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1())); | 4900 Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1())); |
4817 body_exit = current_block(); | 4901 body_exit = current_block(); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4942 return kUseGeneric; | 5026 return kUseGeneric; |
4943 } | 5027 } |
4944 | 5028 |
4945 return kUseCell; | 5029 return kUseCell; |
4946 } | 5030 } |
4947 | 5031 |
4948 | 5032 |
4949 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5033 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
4950 ASSERT(var->IsContextSlot()); | 5034 ASSERT(var->IsContextSlot()); |
4951 HValue* context = environment()->context(); | 5035 HValue* context = environment()->context(); |
4952 int length = current_info()->scope()->ContextChainLength(var->scope()); | 5036 int length = scope()->ContextChainLength(var->scope()); |
4953 while (length-- > 0) { | 5037 while (length-- > 0) { |
4954 context = Add<HLoadNamedField>( | 5038 context = Add<HLoadNamedField>( |
4955 context, static_cast<HValue*>(NULL), | 5039 context, static_cast<HValue*>(NULL), |
4956 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 5040 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
4957 } | 5041 } |
4958 return context; | 5042 return context; |
4959 } | 5043 } |
4960 | 5044 |
4961 | 5045 |
4962 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5046 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5026 if (value == graph()->GetConstantHole()) { | 5110 if (value == graph()->GetConstantHole()) { |
5027 ASSERT(IsDeclaredVariableMode(variable->mode()) && | 5111 ASSERT(IsDeclaredVariableMode(variable->mode()) && |
5028 variable->mode() != VAR); | 5112 variable->mode() != VAR); |
5029 return Bailout(kReferenceToUninitializedVariable); | 5113 return Bailout(kReferenceToUninitializedVariable); |
5030 } | 5114 } |
5031 return ast_context()->ReturnValue(value); | 5115 return ast_context()->ReturnValue(value); |
5032 } | 5116 } |
5033 | 5117 |
5034 case Variable::CONTEXT: { | 5118 case Variable::CONTEXT: { |
5035 HValue* context = BuildContextChainWalk(variable); | 5119 HValue* context = BuildContextChainWalk(variable); |
5036 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable); | 5120 HLoadContextSlot::Mode mode; |
| 5121 switch (variable->mode()) { |
| 5122 case LET: |
| 5123 case CONST: |
| 5124 mode = HLoadContextSlot::kCheckDeoptimize; |
| 5125 break; |
| 5126 case CONST_LEGACY: |
| 5127 mode = HLoadContextSlot::kCheckReturnUndefined; |
| 5128 break; |
| 5129 default: |
| 5130 mode = HLoadContextSlot::kNoCheck; |
| 5131 break; |
| 5132 } |
| 5133 HLoadContextSlot* instr = |
| 5134 new(zone()) HLoadContextSlot(context, variable->index(), mode); |
5037 return ast_context()->ReturnInstruction(instr, expr->id()); | 5135 return ast_context()->ReturnInstruction(instr, expr->id()); |
5038 } | 5136 } |
5039 | 5137 |
5040 case Variable::LOOKUP: | 5138 case Variable::LOOKUP: |
5041 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); | 5139 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); |
5042 } | 5140 } |
5043 } | 5141 } |
5044 | 5142 |
5045 | 5143 |
5046 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { | 5144 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { |
(...skipping 2408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7455 } | 7553 } |
7456 | 7554 |
7457 // Capture the state before invoking the inlined function for deopt in the | 7555 // Capture the state before invoking the inlined function for deopt in the |
7458 // inlined function. This simulate has no bailout-id since it's not directly | 7556 // inlined function. This simulate has no bailout-id since it's not directly |
7459 // reachable for deopt, and is only used to capture the state. If the simulate | 7557 // reachable for deopt, and is only used to capture the state. If the simulate |
7460 // becomes reachable by merging, the ast id of the simulate merged into it is | 7558 // becomes reachable by merging, the ast id of the simulate merged into it is |
7461 // adopted. | 7559 // adopted. |
7462 Add<HSimulate>(BailoutId::None()); | 7560 Add<HSimulate>(BailoutId::None()); |
7463 | 7561 |
7464 current_block()->UpdateEnvironment(inner_env); | 7562 current_block()->UpdateEnvironment(inner_env); |
7465 | 7563 Scope* saved_scope = scope(); |
| 7564 set_scope(target_info.scope()); |
7466 HEnterInlined* enter_inlined = | 7565 HEnterInlined* enter_inlined = |
7467 Add<HEnterInlined>(return_id, target, arguments_count, function, | 7566 Add<HEnterInlined>(return_id, target, arguments_count, function, |
7468 function_state()->inlining_kind(), | 7567 function_state()->inlining_kind(), |
7469 function->scope()->arguments(), | 7568 function->scope()->arguments(), |
7470 arguments_object); | 7569 arguments_object); |
7471 function_state()->set_entry(enter_inlined); | 7570 function_state()->set_entry(enter_inlined); |
7472 | 7571 |
7473 VisitDeclarations(target_info.scope()->declarations()); | 7572 VisitDeclarations(target_info.scope()->declarations()); |
7474 VisitStatements(function->body()); | 7573 VisitStatements(function->body()); |
| 7574 set_scope(saved_scope); |
7475 if (HasStackOverflow()) { | 7575 if (HasStackOverflow()) { |
7476 // Bail out if the inline function did, as we cannot residualize a call | 7576 // Bail out if the inline function did, as we cannot residualize a call |
7477 // instead. | 7577 // instead. |
7478 TraceInline(target, caller, "inline graph construction failed"); | 7578 TraceInline(target, caller, "inline graph construction failed"); |
7479 target_shared->DisableOptimization(kInliningBailedOut); | 7579 target_shared->DisableOptimization(kInliningBailedOut); |
7480 inline_bailout_ = true; | 7580 inline_bailout_ = true; |
7481 delete target_state; | 7581 delete target_state; |
7482 return true; | 7582 return true; |
7483 } | 7583 } |
7484 | 7584 |
(...skipping 3940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11425 frame_type_(JS_FUNCTION), | 11525 frame_type_(JS_FUNCTION), |
11426 parameter_count_(0), | 11526 parameter_count_(0), |
11427 specials_count_(1), | 11527 specials_count_(1), |
11428 local_count_(0), | 11528 local_count_(0), |
11429 outer_(outer), | 11529 outer_(outer), |
11430 entry_(NULL), | 11530 entry_(NULL), |
11431 pop_count_(0), | 11531 pop_count_(0), |
11432 push_count_(0), | 11532 push_count_(0), |
11433 ast_id_(BailoutId::None()), | 11533 ast_id_(BailoutId::None()), |
11434 zone_(zone) { | 11534 zone_(zone) { |
11435 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 11535 Scope* declaration_scope = scope->DeclarationScope(); |
| 11536 Initialize(declaration_scope->num_parameters() + 1, |
| 11537 declaration_scope->num_stack_slots(), 0); |
11436 } | 11538 } |
11437 | 11539 |
11438 | 11540 |
11439 HEnvironment::HEnvironment(Zone* zone, int parameter_count) | 11541 HEnvironment::HEnvironment(Zone* zone, int parameter_count) |
11440 : values_(0, zone), | 11542 : values_(0, zone), |
11441 frame_type_(STUB), | 11543 frame_type_(STUB), |
11442 parameter_count_(parameter_count), | 11544 parameter_count_(parameter_count), |
11443 specials_count_(1), | 11545 specials_count_(1), |
11444 local_count_(0), | 11546 local_count_(0), |
11445 outer_(NULL), | 11547 outer_(NULL), |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12038 if (ShouldProduceTraceOutput()) { | 12140 if (ShouldProduceTraceOutput()) { |
12039 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12141 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12040 } | 12142 } |
12041 | 12143 |
12042 #ifdef DEBUG | 12144 #ifdef DEBUG |
12043 graph_->Verify(false); // No full verify. | 12145 graph_->Verify(false); // No full verify. |
12044 #endif | 12146 #endif |
12045 } | 12147 } |
12046 | 12148 |
12047 } } // namespace v8::internal | 12149 } } // namespace v8::internal |
OLD | NEW |