| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 4722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4733 } | 4733 } |
| 4734 | 4734 |
| 4735 | 4735 |
| 4736 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { | 4736 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
| 4737 ASSERT(!HasStackOverflow()); | 4737 ASSERT(!HasStackOverflow()); |
| 4738 ASSERT(current_block() != NULL); | 4738 ASSERT(current_block() != NULL); |
| 4739 ASSERT(current_block()->HasPredecessor()); | 4739 ASSERT(current_block()->HasPredecessor()); |
| 4740 if (stmt->scope() != NULL) { | 4740 if (stmt->scope() != NULL) { |
| 4741 return Bailout("ScopedBlock"); | 4741 return Bailout("ScopedBlock"); |
| 4742 } | 4742 } |
| 4743 BreakAndContinueInfo break_info(stmt); | 4743 BreakAndContinueInfo break_info(stmt, 0); |
| 4744 { BreakAndContinueScope push(&break_info, this); | 4744 { BreakAndContinueScope push(&break_info, this); |
| 4745 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4745 CHECK_BAILOUT(VisitStatements(stmt->statements())); |
| 4746 } | 4746 } |
| 4747 HBasicBlock* break_block = break_info.break_block(); | 4747 HBasicBlock* break_block = break_info.break_block(); |
| 4748 if (break_block != NULL) { | 4748 if (break_block != NULL) { |
| 4749 if (current_block() != NULL) current_block()->Goto(break_block); | 4749 if (current_block() != NULL) current_block()->Goto(break_block); |
| 4750 break_block->SetJoinId(stmt->ExitId()); | 4750 break_block->SetJoinId(stmt->ExitId()); |
| 4751 set_current_block(break_block); | 4751 set_current_block(break_block); |
| 4752 } | 4752 } |
| 4753 } | 4753 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4801 } else { | 4801 } else { |
| 4802 cond_false = NULL; | 4802 cond_false = NULL; |
| 4803 } | 4803 } |
| 4804 | 4804 |
| 4805 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); | 4805 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); |
| 4806 set_current_block(join); | 4806 set_current_block(join); |
| 4807 } | 4807 } |
| 4808 } | 4808 } |
| 4809 | 4809 |
| 4810 | 4810 |
| 4811 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( | 4811 void HOptimizedGraphBuilder::BreakAndContinueScope::UnwindReturn() { |
| 4812 BreakableStatement* stmt, | |
| 4813 BreakType type, | |
| 4814 int* drop_extra) { | |
| 4815 *drop_extra = 0; | |
| 4816 BreakAndContinueScope* current = this; | 4812 BreakAndContinueScope* current = this; |
| 4817 while (current != NULL && current->info()->target() != stmt) { | 4813 while (current != NULL) { |
| 4818 *drop_extra += current->info()->drop_extra(); | 4814 TryCatchStatement* try_catch = |
| 4815 current->info()->statement()->AsTryCatchStatement(); |
| 4816 if (try_catch != NULL) { |
| 4817 HLeaveTry* leave = new(owner()->zone()) HLeaveTry; |
| 4818 owner()->AddInstruction(leave); |
| 4819 owner()->environment()->RemoveExceptionHandler(); |
| 4820 owner()->AddSimulate(try_catch->TryExitId()); |
| 4821 } |
| 4822 current = current->next(); |
| 4823 } |
| 4824 } |
| 4825 |
| 4826 |
| 4827 void HOptimizedGraphBuilder::BreakAndContinueScope::Unwind(BreakableStatement* t
arget, |
| 4828 BreakType type) { |
| 4829 BreakAndContinueScope* current = this; |
| 4830 while (current != NULL && current->info()->statement() != target) { |
| 4831 TryCatchStatement* try_catch = |
| 4832 current->info()->statement()->AsTryCatchStatement(); |
| 4833 if (try_catch != NULL) { |
| 4834 HLeaveTry* leave = new(owner()->zone()) HLeaveTry; |
| 4835 owner()->AddInstruction(leave); |
| 4836 owner()->environment()->RemoveExceptionHandler(); |
| 4837 owner()->AddSimulate(try_catch->TryExitId()); |
| 4838 } |
| 4839 owner()->Drop(current->info()->drop_extra()); |
| 4819 current = current->next(); | 4840 current = current->next(); |
| 4820 } | 4841 } |
| 4821 ASSERT(current != NULL); // Always found (unless stack is malformed). | 4842 ASSERT(current != NULL); // Always found (unless stack is malformed). |
| 4822 | 4843 |
| 4823 if (type == BREAK) { | 4844 if (type == BREAK) { |
| 4824 *drop_extra += current->info()->drop_extra(); | 4845 owner()->Drop(current->info()->drop_extra()); |
| 4825 } | 4846 } |
| 4826 | 4847 |
| 4827 HBasicBlock* block = NULL; | 4848 HBasicBlock* block = NULL; |
| 4828 switch (type) { | 4849 switch (type) { |
| 4829 case BREAK: | 4850 case BREAK: |
| 4830 block = current->info()->break_block(); | 4851 block = current->info()->break_block(); |
| 4831 if (block == NULL) { | 4852 if (block == NULL) { |
| 4832 block = current->owner()->graph()->CreateBasicBlock(); | 4853 block = current->owner()->graph()->CreateBasicBlock(); |
| 4833 current->info()->set_break_block(block); | 4854 current->info()->set_break_block(block); |
| 4834 } | 4855 } |
| 4835 break; | 4856 break; |
| 4836 | 4857 |
| 4837 case CONTINUE: | 4858 case CONTINUE: |
| 4838 block = current->info()->continue_block(); | 4859 block = current->info()->continue_block(); |
| 4839 if (block == NULL) { | 4860 if (block == NULL) { |
| 4840 block = current->owner()->graph()->CreateBasicBlock(); | 4861 block = current->owner()->graph()->CreateBasicBlock(); |
| 4841 current->info()->set_continue_block(block); | 4862 current->info()->set_continue_block(block); |
| 4842 } | 4863 } |
| 4843 break; | 4864 break; |
| 4844 } | 4865 } |
| 4845 | 4866 owner()->current_block()->Goto(block); |
| 4846 return block; | 4867 owner()->set_current_block(NULL); |
| 4847 } | 4868 } |
| 4848 | 4869 |
| 4849 | 4870 |
| 4850 void HOptimizedGraphBuilder::VisitContinueStatement( | 4871 void HOptimizedGraphBuilder::VisitContinueStatement( |
| 4851 ContinueStatement* stmt) { | 4872 ContinueStatement* stmt) { |
| 4852 ASSERT(!HasStackOverflow()); | 4873 ASSERT(!HasStackOverflow()); |
| 4853 ASSERT(current_block() != NULL); | 4874 ASSERT(current_block() != NULL); |
| 4854 ASSERT(current_block()->HasPredecessor()); | 4875 ASSERT(current_block()->HasPredecessor()); |
| 4855 int drop_extra = 0; | 4876 break_scope()->Unwind(stmt->target(), BreakAndContinueScope::CONTINUE); |
| 4856 HBasicBlock* continue_block = break_scope()->Get( | |
| 4857 stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra); | |
| 4858 Drop(drop_extra); | |
| 4859 current_block()->Goto(continue_block); | |
| 4860 set_current_block(NULL); | |
| 4861 } | 4877 } |
| 4862 | 4878 |
| 4863 | 4879 |
| 4864 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { | 4880 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { |
| 4865 ASSERT(!HasStackOverflow()); | 4881 ASSERT(!HasStackOverflow()); |
| 4866 ASSERT(current_block() != NULL); | 4882 ASSERT(current_block() != NULL); |
| 4867 ASSERT(current_block()->HasPredecessor()); | 4883 ASSERT(current_block()->HasPredecessor()); |
| 4868 int drop_extra = 0; | 4884 break_scope()->Unwind(stmt->target(), BreakAndContinueScope::BREAK); |
| 4869 HBasicBlock* break_block = break_scope()->Get( | |
| 4870 stmt->target(), BreakAndContinueScope::BREAK, &drop_extra); | |
| 4871 Drop(drop_extra); | |
| 4872 current_block()->Goto(break_block); | |
| 4873 set_current_block(NULL); | |
| 4874 } | 4885 } |
| 4875 | 4886 |
| 4876 | 4887 |
| 4877 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 4888 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
| 4878 ASSERT(!HasStackOverflow()); | 4889 ASSERT(!HasStackOverflow()); |
| 4879 ASSERT(current_block() != NULL); | 4890 ASSERT(current_block() != NULL); |
| 4880 ASSERT(current_block()->HasPredecessor()); | 4891 ASSERT(current_block()->HasPredecessor()); |
| 4881 FunctionState* state = function_state(); | 4892 FunctionState* state = function_state(); |
| 4882 AstContext* context = call_context(); | 4893 AstContext* context = call_context(); |
| 4883 if (context == NULL) { | 4894 if (context == NULL) { |
| 4884 // Not an inlined return, so an actual one. | 4895 // Not an inlined return, so an actual one. |
| 4885 CHECK_ALIVE(VisitForValue(stmt->expression())); | 4896 CHECK_ALIVE(VisitForValue(stmt->expression())); |
| 4886 HValue* result = environment()->Pop(); | 4897 HValue* result = environment()->Pop(); |
| 4898 break_scope()->UnwindReturn(); |
| 4887 AddReturn(result); | 4899 AddReturn(result); |
| 4888 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { | 4900 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { |
| 4889 // Return from an inlined construct call. In a test context the return value | 4901 // Return from an inlined construct call. In a test context the return value |
| 4890 // will always evaluate to true, in a value context the return value needs | 4902 // will always evaluate to true, in a value context the return value needs |
| 4891 // to be a JSObject. | 4903 // to be a JSObject. |
| 4892 if (context->IsTest()) { | 4904 if (context->IsTest()) { |
| 4893 TestContext* test = TestContext::cast(context); | 4905 TestContext* test = TestContext::cast(context); |
| 4894 CHECK_ALIVE(VisitForEffect(stmt->expression())); | 4906 CHECK_ALIVE(VisitForEffect(stmt->expression())); |
| 4895 current_block()->Goto(test->if_true(), state); | 4907 current_block()->Goto(test->if_true(), state); |
| 4896 } else if (context->IsEffect()) { | 4908 } else if (context->IsEffect()) { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5046 if (not_string_block != NULL) { | 5058 if (not_string_block != NULL) { |
| 5047 BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId(); | 5059 BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId(); |
| 5048 last_block = CreateJoin(last_block, not_string_block, join_id); | 5060 last_block = CreateJoin(last_block, not_string_block, join_id); |
| 5049 } | 5061 } |
| 5050 | 5062 |
| 5051 // 2. Loop over the clauses and the linked list of tests in lockstep, | 5063 // 2. Loop over the clauses and the linked list of tests in lockstep, |
| 5052 // translating the clause bodies. | 5064 // translating the clause bodies. |
| 5053 HBasicBlock* curr_test_block = first_test_block; | 5065 HBasicBlock* curr_test_block = first_test_block; |
| 5054 HBasicBlock* fall_through_block = NULL; | 5066 HBasicBlock* fall_through_block = NULL; |
| 5055 | 5067 |
| 5056 BreakAndContinueInfo break_info(stmt); | 5068 BreakAndContinueInfo break_info(stmt, 0); |
| 5057 { BreakAndContinueScope push(&break_info, this); | 5069 { BreakAndContinueScope push(&break_info, this); |
| 5058 for (int i = 0; i < clause_count; ++i) { | 5070 for (int i = 0; i < clause_count; ++i) { |
| 5059 CaseClause* clause = clauses->at(i); | 5071 CaseClause* clause = clauses->at(i); |
| 5060 | 5072 |
| 5061 // Identify the block where normal (non-fall-through) control flow | 5073 // Identify the block where normal (non-fall-through) control flow |
| 5062 // goes to. | 5074 // goes to. |
| 5063 HBasicBlock* normal_block = NULL; | 5075 HBasicBlock* normal_block = NULL; |
| 5064 if (clause->is_default()) { | 5076 if (clause->is_default()) { |
| 5065 if (last_block != NULL) { | 5077 if (last_block != NULL) { |
| 5066 normal_block = last_block; | 5078 normal_block = last_block; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5191 ASSERT(!HasStackOverflow()); | 5203 ASSERT(!HasStackOverflow()); |
| 5192 ASSERT(current_block() != NULL); | 5204 ASSERT(current_block() != NULL); |
| 5193 ASSERT(current_block()->HasPredecessor()); | 5205 ASSERT(current_block()->HasPredecessor()); |
| 5194 ASSERT(current_block() != NULL); | 5206 ASSERT(current_block() != NULL); |
| 5195 bool osr_entry = PreProcessOsrEntry(stmt); | 5207 bool osr_entry = PreProcessOsrEntry(stmt); |
| 5196 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5208 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
| 5197 current_block()->Goto(loop_entry); | 5209 current_block()->Goto(loop_entry); |
| 5198 set_current_block(loop_entry); | 5210 set_current_block(loop_entry); |
| 5199 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5211 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
| 5200 | 5212 |
| 5201 BreakAndContinueInfo break_info(stmt); | 5213 BreakAndContinueInfo break_info(stmt, 0); |
| 5202 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 5214 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
| 5203 HBasicBlock* body_exit = | 5215 HBasicBlock* body_exit = |
| 5204 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5216 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 5205 HBasicBlock* loop_successor = NULL; | 5217 HBasicBlock* loop_successor = NULL; |
| 5206 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { | 5218 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
| 5207 set_current_block(body_exit); | 5219 set_current_block(body_exit); |
| 5208 // The block for a true condition, the actual predecessor block of the | 5220 // The block for a true condition, the actual predecessor block of the |
| 5209 // back edge. | 5221 // back edge. |
| 5210 body_exit = graph()->CreateBasicBlock(); | 5222 body_exit = graph()->CreateBasicBlock(); |
| 5211 loop_successor = graph()->CreateBasicBlock(); | 5223 loop_successor = graph()->CreateBasicBlock(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5252 body_entry->SetJoinId(stmt->BodyId()); | 5264 body_entry->SetJoinId(stmt->BodyId()); |
| 5253 set_current_block(body_entry); | 5265 set_current_block(body_entry); |
| 5254 } | 5266 } |
| 5255 if (loop_successor->HasPredecessor()) { | 5267 if (loop_successor->HasPredecessor()) { |
| 5256 loop_successor->SetJoinId(stmt->ExitId()); | 5268 loop_successor->SetJoinId(stmt->ExitId()); |
| 5257 } else { | 5269 } else { |
| 5258 loop_successor = NULL; | 5270 loop_successor = NULL; |
| 5259 } | 5271 } |
| 5260 } | 5272 } |
| 5261 | 5273 |
| 5262 BreakAndContinueInfo break_info(stmt); | 5274 BreakAndContinueInfo break_info(stmt, 0); |
| 5263 if (current_block() != NULL) { | 5275 if (current_block() != NULL) { |
| 5264 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 5276 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
| 5265 } | 5277 } |
| 5266 HBasicBlock* body_exit = | 5278 HBasicBlock* body_exit = |
| 5267 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5279 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 5268 HBasicBlock* loop_exit = CreateLoop(stmt, | 5280 HBasicBlock* loop_exit = CreateLoop(stmt, |
| 5269 loop_entry, | 5281 loop_entry, |
| 5270 body_exit, | 5282 body_exit, |
| 5271 loop_successor, | 5283 loop_successor, |
| 5272 break_info.break_block()); | 5284 break_info.break_block()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 5297 body_entry->SetJoinId(stmt->BodyId()); | 5309 body_entry->SetJoinId(stmt->BodyId()); |
| 5298 set_current_block(body_entry); | 5310 set_current_block(body_entry); |
| 5299 } | 5311 } |
| 5300 if (loop_successor->HasPredecessor()) { | 5312 if (loop_successor->HasPredecessor()) { |
| 5301 loop_successor->SetJoinId(stmt->ExitId()); | 5313 loop_successor->SetJoinId(stmt->ExitId()); |
| 5302 } else { | 5314 } else { |
| 5303 loop_successor = NULL; | 5315 loop_successor = NULL; |
| 5304 } | 5316 } |
| 5305 } | 5317 } |
| 5306 | 5318 |
| 5307 BreakAndContinueInfo break_info(stmt); | 5319 BreakAndContinueInfo break_info(stmt, 0); |
| 5308 if (current_block() != NULL) { | 5320 if (current_block() != NULL) { |
| 5309 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 5321 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
| 5310 } | 5322 } |
| 5311 HBasicBlock* body_exit = | 5323 HBasicBlock* body_exit = |
| 5312 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5324 JoinContinue(stmt, current_block(), break_info.continue_block()); |
| 5313 | 5325 |
| 5314 if (stmt->next() != NULL && body_exit != NULL) { | 5326 if (stmt->next() != NULL && body_exit != NULL) { |
| 5315 set_current_block(body_exit); | 5327 set_current_block(body_exit); |
| 5316 CHECK_BAILOUT(Visit(stmt->next())); | 5328 CHECK_BAILOUT(Visit(stmt->next())); |
| 5317 body_exit = current_block(); | 5329 body_exit = current_block(); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5452 ASSERT(current_block() != NULL); | 5464 ASSERT(current_block() != NULL); |
| 5453 ASSERT(current_block()->HasPredecessor()); | 5465 ASSERT(current_block()->HasPredecessor()); |
| 5454 return Bailout("ForOfStatement"); | 5466 return Bailout("ForOfStatement"); |
| 5455 } | 5467 } |
| 5456 | 5468 |
| 5457 | 5469 |
| 5458 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 5470 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| 5459 ASSERT(!HasStackOverflow()); | 5471 ASSERT(!HasStackOverflow()); |
| 5460 ASSERT(current_block() != NULL); | 5472 ASSERT(current_block() != NULL); |
| 5461 ASSERT(current_block()->HasPredecessor()); | 5473 ASSERT(current_block()->HasPredecessor()); |
| 5462 return Bailout("TryCatchStatement"); | 5474 if (!FLAG_crankshaft_try_support) { |
| 5475 Bailout("try statement support disabled"); |
| 5476 return; |
| 5477 } |
| 5478 HEnterTry* enter = new(zone()) HEnterTry(stmt->index()); |
| 5479 AddInstruction(enter); |
| 5480 environment()->AddExceptionHandler(); |
| 5481 AddSimulate(stmt->TryEntryId()); |
| 5482 BreakAndContinueInfo try_info(stmt, 0); |
| 5483 { BreakAndContinueScope push(&try_info, this); |
| 5484 CHECK_BAILOUT(Visit(stmt->try_block())); |
| 5485 } |
| 5486 if (current_block() != NULL) { |
| 5487 HLeaveTry* leave = new(zone()) HLeaveTry; |
| 5488 AddInstruction(leave); |
| 5489 environment()->RemoveExceptionHandler(); |
| 5490 AddSimulate(stmt->TryExitId()); |
| 5491 } |
| 5463 } | 5492 } |
| 5464 | 5493 |
| 5465 | 5494 |
| 5466 void HOptimizedGraphBuilder::VisitTryFinallyStatement( | 5495 void HOptimizedGraphBuilder::VisitTryFinallyStatement( |
| 5467 TryFinallyStatement* stmt) { | 5496 TryFinallyStatement* stmt) { |
| 5468 ASSERT(!HasStackOverflow()); | 5497 ASSERT(!HasStackOverflow()); |
| 5469 ASSERT(current_block() != NULL); | 5498 ASSERT(current_block() != NULL); |
| 5470 ASSERT(current_block()->HasPredecessor()); | 5499 ASSERT(current_block()->HasPredecessor()); |
| 5471 return Bailout("TryFinallyStatement"); | 5500 return Bailout("TryFinallyStatement"); |
| 5472 } | 5501 } |
| (...skipping 5436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10909 HEnvironment::HEnvironment(HEnvironment* outer, | 10938 HEnvironment::HEnvironment(HEnvironment* outer, |
| 10910 Scope* scope, | 10939 Scope* scope, |
| 10911 Handle<JSFunction> closure, | 10940 Handle<JSFunction> closure, |
| 10912 Zone* zone) | 10941 Zone* zone) |
| 10913 : closure_(closure), | 10942 : closure_(closure), |
| 10914 values_(0, zone), | 10943 values_(0, zone), |
| 10915 frame_type_(JS_FUNCTION), | 10944 frame_type_(JS_FUNCTION), |
| 10916 parameter_count_(0), | 10945 parameter_count_(0), |
| 10917 specials_count_(1), | 10946 specials_count_(1), |
| 10918 local_count_(0), | 10947 local_count_(0), |
| 10948 handler_count_(0), |
| 10919 outer_(outer), | 10949 outer_(outer), |
| 10920 entry_(NULL), | 10950 entry_(NULL), |
| 10921 pop_count_(0), | 10951 pop_count_(0), |
| 10922 push_count_(0), | 10952 push_count_(0), |
| 10923 ast_id_(BailoutId::None()), | 10953 ast_id_(BailoutId::None()), |
| 10924 zone_(zone) { | 10954 zone_(zone) { |
| 10925 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 10955 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
| 10926 } | 10956 } |
| 10927 | 10957 |
| 10928 | 10958 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 10941 Initialize(parameter_count, 0, 0); | 10971 Initialize(parameter_count, 0, 0); |
| 10942 } | 10972 } |
| 10943 | 10973 |
| 10944 | 10974 |
| 10945 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) | 10975 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
| 10946 : values_(0, zone), | 10976 : values_(0, zone), |
| 10947 frame_type_(JS_FUNCTION), | 10977 frame_type_(JS_FUNCTION), |
| 10948 parameter_count_(0), | 10978 parameter_count_(0), |
| 10949 specials_count_(0), | 10979 specials_count_(0), |
| 10950 local_count_(0), | 10980 local_count_(0), |
| 10981 handler_count_(0), |
| 10951 outer_(NULL), | 10982 outer_(NULL), |
| 10952 entry_(NULL), | 10983 entry_(NULL), |
| 10953 pop_count_(0), | 10984 pop_count_(0), |
| 10954 push_count_(0), | 10985 push_count_(0), |
| 10955 ast_id_(other->ast_id()), | 10986 ast_id_(other->ast_id()), |
| 10956 zone_(zone) { | 10987 zone_(zone) { |
| 10957 Initialize(other); | 10988 Initialize(other); |
| 10958 } | 10989 } |
| 10959 | 10990 |
| 10960 | 10991 |
| 10961 HEnvironment::HEnvironment(HEnvironment* outer, | 10992 HEnvironment::HEnvironment(HEnvironment* outer, |
| 10962 Handle<JSFunction> closure, | 10993 Handle<JSFunction> closure, |
| 10963 FrameType frame_type, | 10994 FrameType frame_type, |
| 10964 int arguments, | 10995 int arguments, |
| 10965 Zone* zone) | 10996 Zone* zone) |
| 10966 : closure_(closure), | 10997 : closure_(closure), |
| 10967 values_(arguments, zone), | 10998 values_(arguments, zone), |
| 10968 frame_type_(frame_type), | 10999 frame_type_(frame_type), |
| 10969 parameter_count_(arguments), | 11000 parameter_count_(arguments), |
| 10970 specials_count_(0), | 11001 specials_count_(0), |
| 10971 local_count_(0), | 11002 local_count_(0), |
| 11003 handler_count_(0), |
| 10972 outer_(outer), | 11004 outer_(outer), |
| 10973 entry_(NULL), | 11005 entry_(NULL), |
| 10974 pop_count_(0), | 11006 pop_count_(0), |
| 10975 push_count_(0), | 11007 push_count_(0), |
| 10976 ast_id_(BailoutId::None()), | 11008 ast_id_(BailoutId::None()), |
| 10977 zone_(zone) { | 11009 zone_(zone) { |
| 10978 } | 11010 } |
| 10979 | 11011 |
| 10980 | 11012 |
| 10981 void HEnvironment::Initialize(int parameter_count, | 11013 void HEnvironment::Initialize(int parameter_count, |
| 10982 int local_count, | 11014 int local_count, |
| 10983 int stack_height) { | 11015 int stack_height) { |
| 10984 parameter_count_ = parameter_count; | 11016 parameter_count_ = parameter_count; |
| 10985 local_count_ = local_count; | 11017 local_count_ = local_count; |
| 10986 | 11018 |
| 10987 // Avoid reallocating the temporaries' backing store on the first Push. | 11019 // Avoid reallocating the temporaries' backing store on the first Push. |
| 10988 int total = parameter_count + specials_count_ + local_count + stack_height; | 11020 int total = parameter_count + specials_count_ + local_count + stack_height; |
| 10989 values_.Initialize(total + 4, zone()); | 11021 values_.Initialize(total + 4, zone()); |
| 10990 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); | 11022 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); |
| 10991 } | 11023 } |
| 10992 | 11024 |
| 10993 | 11025 |
| 10994 void HEnvironment::Initialize(const HEnvironment* other) { | 11026 void HEnvironment::Initialize(const HEnvironment* other) { |
| 10995 closure_ = other->closure(); | 11027 closure_ = other->closure(); |
| 10996 values_.AddAll(other->values_, zone()); | 11028 values_.AddAll(other->values_, zone()); |
| 10997 assigned_variables_.Union(other->assigned_variables_, zone()); | 11029 assigned_variables_.Union(other->assigned_variables_, zone()); |
| 10998 frame_type_ = other->frame_type_; | 11030 frame_type_ = other->frame_type_; |
| 10999 parameter_count_ = other->parameter_count_; | 11031 parameter_count_ = other->parameter_count_; |
| 11000 local_count_ = other->local_count_; | 11032 local_count_ = other->local_count_; |
| 11033 handler_count_ = other->handler_count_; |
| 11001 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 11034 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
| 11002 entry_ = other->entry_; | 11035 entry_ = other->entry_; |
| 11003 pop_count_ = other->pop_count_; | 11036 pop_count_ = other->pop_count_; |
| 11004 push_count_ = other->push_count_; | 11037 push_count_ = other->push_count_; |
| 11005 specials_count_ = other->specials_count_; | 11038 specials_count_ = other->specials_count_; |
| 11006 ast_id_ = other->ast_id_; | 11039 ast_id_ = other->ast_id_; |
| 11007 } | 11040 } |
| 11008 | 11041 |
| 11009 | 11042 |
| 11010 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 11043 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
| 11011 ASSERT(!block->IsLoopHeader()); | 11044 ASSERT(!block->IsLoopHeader()); |
| 11012 ASSERT(values_.length() == other->values_.length()); | 11045 ASSERT(values_.length() == other->values_.length()); |
| 11046 ASSERT(handler_count_ == other->handler_count_); |
| 11013 | 11047 |
| 11014 int length = values_.length(); | 11048 int length = values_.length(); |
| 11015 for (int i = 0; i < length; ++i) { | 11049 for (int i = 0; i < length; ++i) { |
| 11016 HValue* value = values_[i]; | 11050 HValue* value = values_[i]; |
| 11017 if (value != NULL && value->IsPhi() && value->block() == block) { | 11051 if (value != NULL && value->IsPhi() && value->block() == block) { |
| 11018 // There is already a phi for the i'th value. | 11052 // There is already a phi for the i'th value. |
| 11019 HPhi* phi = HPhi::cast(value); | 11053 HPhi* phi = HPhi::cast(value); |
| 11020 // Assert index is correct and that we haven't missed an incoming edge. | 11054 // Assert index is correct and that we haven't missed an incoming edge. |
| 11021 ASSERT(phi->merged_index() == i); | 11055 ASSERT(phi->merged_index() == i); |
| 11022 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 11056 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11571 } | 11605 } |
| 11572 } | 11606 } |
| 11573 | 11607 |
| 11574 #ifdef DEBUG | 11608 #ifdef DEBUG |
| 11575 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11609 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11576 if (allocator_ != NULL) allocator_->Verify(); | 11610 if (allocator_ != NULL) allocator_->Verify(); |
| 11577 #endif | 11611 #endif |
| 11578 } | 11612 } |
| 11579 | 11613 |
| 11580 } } // namespace v8::internal | 11614 } } // namespace v8::internal |
| OLD | NEW |