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 |