| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
| 10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 | 55 |
| 56 | 56 |
| 57 bool AstGraphBuilder::CreateGraph() { | 57 bool AstGraphBuilder::CreateGraph() { |
| 58 Scope* scope = info()->scope(); | 58 Scope* scope = info()->scope(); |
| 59 DCHECK(graph() != NULL); | 59 DCHECK(graph() != NULL); |
| 60 | 60 |
| 61 // Set up the basic structure of the graph. | 61 // Set up the basic structure of the graph. |
| 62 int parameter_count = info()->num_parameters(); | 62 int parameter_count = info()->num_parameters(); |
| 63 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); | 63 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); |
| 64 | 64 |
| 65 Node* start = graph()->start(); |
| 65 // Initialize the top-level environment. | 66 // Initialize the top-level environment. |
| 66 Environment env(this, scope, graph()->start()); | 67 Environment env(this, scope, start); |
| 67 set_environment(&env); | 68 set_environment(&env); |
| 68 | 69 |
| 70 if (info()->is_osr()) { |
| 71 // Use OSR normal entry as the start of the top-level environment. |
| 72 // It will be replaced with {Dead} after typing and optimizations. |
| 73 NewNode(common()->OsrNormalEntry()); |
| 74 } |
| 75 |
| 69 // Initialize the incoming context. | 76 // Initialize the incoming context. |
| 70 Node* outer_context = GetFunctionContext(); | 77 Node* outer_context = GetFunctionContext(); |
| 71 set_current_context(outer_context); | 78 set_current_context(outer_context); |
| 72 | 79 |
| 73 // Build receiver check for sloppy mode if necessary. | 80 // Build receiver check for sloppy mode if necessary. |
| 74 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 81 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
| 75 Node* original_receiver = env.Lookup(scope->receiver()); | 82 Node* original_receiver = env.Lookup(scope->receiver()); |
| 76 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 83 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 77 env.Bind(scope->receiver(), patched_receiver); | 84 env.Bind(scope->receiver(), patched_receiver); |
| 78 | 85 |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 VisitStatements(clause->statements()); | 589 VisitStatements(clause->statements()); |
| 583 compare_switch.EndCase(); | 590 compare_switch.EndCase(); |
| 584 } | 591 } |
| 585 | 592 |
| 586 compare_switch.EndSwitch(); | 593 compare_switch.EndSwitch(); |
| 587 } | 594 } |
| 588 | 595 |
| 589 | 596 |
| 590 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 597 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 591 LoopBuilder while_loop(this); | 598 LoopBuilder while_loop(this); |
| 592 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt)); | 599 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); |
| 593 VisitIterationBody(stmt, &while_loop, 0); | 600 VisitIterationBody(stmt, &while_loop, 0); |
| 594 while_loop.EndBody(); | 601 while_loop.EndBody(); |
| 595 VisitForTest(stmt->cond()); | 602 VisitForTest(stmt->cond()); |
| 596 Node* condition = environment()->Pop(); | 603 Node* condition = environment()->Pop(); |
| 597 while_loop.BreakUnless(condition); | 604 while_loop.BreakUnless(condition); |
| 598 while_loop.EndLoop(); | 605 while_loop.EndLoop(); |
| 599 } | 606 } |
| 600 | 607 |
| 601 | 608 |
| 602 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 609 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
| 603 LoopBuilder while_loop(this); | 610 LoopBuilder while_loop(this); |
| 604 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt)); | 611 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); |
| 605 VisitForTest(stmt->cond()); | 612 VisitForTest(stmt->cond()); |
| 606 Node* condition = environment()->Pop(); | 613 Node* condition = environment()->Pop(); |
| 607 while_loop.BreakUnless(condition); | 614 while_loop.BreakUnless(condition); |
| 608 VisitIterationBody(stmt, &while_loop, 0); | 615 VisitIterationBody(stmt, &while_loop, 0); |
| 609 while_loop.EndBody(); | 616 while_loop.EndBody(); |
| 610 while_loop.EndLoop(); | 617 while_loop.EndLoop(); |
| 611 } | 618 } |
| 612 | 619 |
| 613 | 620 |
| 614 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { | 621 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| 615 LoopBuilder for_loop(this); | 622 LoopBuilder for_loop(this); |
| 616 VisitIfNotNull(stmt->init()); | 623 VisitIfNotNull(stmt->init()); |
| 617 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt)); | 624 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); |
| 618 if (stmt->cond() != NULL) { | 625 if (stmt->cond() != NULL) { |
| 619 VisitForTest(stmt->cond()); | 626 VisitForTest(stmt->cond()); |
| 620 Node* condition = environment()->Pop(); | 627 Node* condition = environment()->Pop(); |
| 621 for_loop.BreakUnless(condition); | 628 for_loop.BreakUnless(condition); |
| 622 } else { | 629 } else { |
| 623 for_loop.BreakUnless(jsgraph()->TrueConstant()); | 630 for_loop.BreakUnless(jsgraph()->TrueConstant()); |
| 624 } | 631 } |
| 625 VisitIterationBody(stmt, &for_loop, 0); | 632 VisitIterationBody(stmt, &for_loop, 0); |
| 626 for_loop.EndBody(); | 633 for_loop.EndBody(); |
| 627 VisitIfNotNull(stmt->next()); | 634 VisitIfNotNull(stmt->next()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 environment()->Pop(); | 690 environment()->Pop(); |
| 684 have_no_properties.Else(); | 691 have_no_properties.Else(); |
| 685 { | 692 { |
| 686 // Construct the rest of the environment. | 693 // Construct the rest of the environment. |
| 687 environment()->Push(cache_type); | 694 environment()->Push(cache_type); |
| 688 environment()->Push(cache_array); | 695 environment()->Push(cache_array); |
| 689 environment()->Push(cache_length); | 696 environment()->Push(cache_length); |
| 690 environment()->Push(jsgraph()->ZeroConstant()); | 697 environment()->Push(jsgraph()->ZeroConstant()); |
| 691 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 698 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 692 LoopBuilder for_loop(this); | 699 LoopBuilder for_loop(this); |
| 693 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt)); | 700 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), |
| 701 IsOsrLoopEntry(stmt)); |
| 694 // Check loop termination condition. | 702 // Check loop termination condition. |
| 695 Node* index = environment()->Peek(0); | 703 Node* index = environment()->Peek(0); |
| 696 Node* exit_cond = | 704 Node* exit_cond = |
| 697 NewNode(javascript()->LessThan(), index, cache_length); | 705 NewNode(javascript()->LessThan(), index, cache_length); |
| 698 // TODO(jarin): provide real bailout id. | 706 // TODO(jarin): provide real bailout id. |
| 699 PrepareFrameState(exit_cond, BailoutId::None()); | 707 PrepareFrameState(exit_cond, BailoutId::None()); |
| 700 for_loop.BreakUnless(exit_cond); | 708 for_loop.BreakUnless(exit_cond); |
| 701 // TODO(dcarney): this runtime call should be a handful of | 709 // TODO(dcarney): this runtime call should be a handful of |
| 702 // simplified instructions that | 710 // simplified instructions that |
| 703 // basically produce | 711 // basically produce |
| (...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2202 Node* tag = NewNode(jsgraph()->machine()->UintLessThan(), limit, stack); | 2210 Node* tag = NewNode(jsgraph()->machine()->UintLessThan(), limit, stack); |
| 2203 stack_check.If(tag, BranchHint::kTrue); | 2211 stack_check.If(tag, BranchHint::kTrue); |
| 2204 stack_check.Then(); | 2212 stack_check.Then(); |
| 2205 stack_check.Else(); | 2213 stack_check.Else(); |
| 2206 Node* guard = NewNode(javascript()->CallRuntime(Runtime::kStackGuard, 0)); | 2214 Node* guard = NewNode(javascript()->CallRuntime(Runtime::kStackGuard, 0)); |
| 2207 stack_check.End(); | 2215 stack_check.End(); |
| 2208 return guard; | 2216 return guard; |
| 2209 } | 2217 } |
| 2210 | 2218 |
| 2211 | 2219 |
| 2220 bool AstGraphBuilder::IsOsrLoopEntry(IterationStatement* stmt) { |
| 2221 return info()->osr_ast_id() == stmt->OsrEntryId(); |
| 2222 } |
| 2223 |
| 2224 |
| 2212 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, | 2225 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, |
| 2213 OutputFrameStateCombine combine) { | 2226 OutputFrameStateCombine combine) { |
| 2214 if (OperatorProperties::HasFrameStateInput(node->op())) { | 2227 if (OperatorProperties::HasFrameStateInput(node->op())) { |
| 2215 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == | 2228 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == |
| 2216 IrOpcode::kDead); | 2229 IrOpcode::kDead); |
| 2217 NodeProperties::ReplaceFrameStateInput( | 2230 NodeProperties::ReplaceFrameStateInput( |
| 2218 node, environment()->Checkpoint(ast_id, combine)); | 2231 node, environment()->Checkpoint(ast_id, combine)); |
| 2219 } | 2232 } |
| 2220 } | 2233 } |
| 2221 | 2234 |
| 2222 | 2235 |
| 2223 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 2236 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
| 2224 IterationStatement* stmt) { | 2237 IterationStatement* stmt) { |
| 2225 if (loop_assignment_analysis_ == NULL) return NULL; | 2238 if (loop_assignment_analysis_ == NULL) return NULL; |
| 2226 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 2239 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); |
| 2227 } | 2240 } |
| 2228 | 2241 |
| 2229 } // namespace compiler | 2242 } // namespace compiler |
| 2230 } // namespace internal | 2243 } // namespace internal |
| 2231 } // namespace v8 | 2244 } // namespace v8 |
| OLD | NEW |