| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/bytecode-graph-builder.h" | 5 #include "src/compiler/bytecode-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/compiler/bytecode-branch-analysis.h" | 7 #include "src/compiler/bytecode-branch-analysis.h" |
| 8 #include "src/compiler/linkage.h" | 8 #include "src/compiler/linkage.h" |
| 9 #include "src/compiler/operator-properties.h" | 9 #include "src/compiler/operator-properties.h" |
| 10 #include "src/interpreter/bytecodes.h" | 10 #include "src/interpreter/bytecodes.h" |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 | 526 |
| 527 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { | 527 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
| 528 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); | 528 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); |
| 529 FeedbackVectorSlot slot; | 529 FeedbackVectorSlot slot; |
| 530 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { | 530 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { |
| 531 slot = feedback_vector->ToSlot(slot_id); | 531 slot = feedback_vector->ToSlot(slot_id); |
| 532 } | 532 } |
| 533 return VectorSlotPair(feedback_vector, slot); | 533 return VectorSlotPair(feedback_vector, slot); |
| 534 } | 534 } |
| 535 | 535 |
| 536 | 536 bool BytecodeGraphBuilder::CreateGraph() { |
| 537 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { | |
| 538 // Set up the basic structure of the graph. Outputs for {Start} are | 537 // Set up the basic structure of the graph. Outputs for {Start} are |
| 539 // the formal parameters (including the receiver) plus context and | 538 // the formal parameters (including the receiver) plus context and |
| 540 // closure. | 539 // closure. |
| 541 | 540 |
| 542 // Set up the basic structure of the graph. Outputs for {Start} are the formal | 541 // Set up the basic structure of the graph. Outputs for {Start} are the formal |
| 543 // parameters (including the receiver) plus new target, number of arguments, | 542 // parameters (including the receiver) plus new target, number of arguments, |
| 544 // context and closure. | 543 // context and closure. |
| 545 int actual_parameter_count = bytecode_array()->parameter_count() + 4; | 544 int actual_parameter_count = bytecode_array()->parameter_count() + 4; |
| 546 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 545 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
| 547 | 546 |
| 548 Environment env(this, bytecode_array()->register_count(), | 547 Environment env(this, bytecode_array()->register_count(), |
| 549 bytecode_array()->parameter_count(), graph()->start(), | 548 bytecode_array()->parameter_count(), graph()->start(), |
| 550 GetFunctionContext()); | 549 GetFunctionContext()); |
| 551 set_environment(&env); | 550 set_environment(&env); |
| 552 | 551 |
| 553 CreateGraphBody(stack_check); | 552 VisitBytecodes(); |
| 554 | 553 |
| 555 // Finish the basic structure of the graph. | 554 // Finish the basic structure of the graph. |
| 556 DCHECK_NE(0u, exit_controls_.size()); | 555 DCHECK_NE(0u, exit_controls_.size()); |
| 557 int const input_count = static_cast<int>(exit_controls_.size()); | 556 int const input_count = static_cast<int>(exit_controls_.size()); |
| 558 Node** const inputs = &exit_controls_.front(); | 557 Node** const inputs = &exit_controls_.front(); |
| 559 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); | 558 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); |
| 560 graph()->SetEnd(end); | 559 graph()->SetEnd(end); |
| 561 | 560 |
| 562 return true; | 561 return true; |
| 563 } | 562 } |
| 564 | 563 |
| 565 | |
| 566 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) { | |
| 567 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments | |
| 568 // object setup, this function variable if used, tracing hooks. | |
| 569 | |
| 570 if (stack_check) { | |
| 571 Node* node = NewNode(javascript()->StackCheck()); | |
| 572 PrepareEntryFrameState(node); | |
| 573 } | |
| 574 | |
| 575 VisitBytecodes(); | |
| 576 } | |
| 577 | |
| 578 | |
| 579 void BytecodeGraphBuilder::VisitBytecodes() { | 564 void BytecodeGraphBuilder::VisitBytecodes() { |
| 580 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone()); | 565 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone()); |
| 581 analysis.Analyze(); | 566 analysis.Analyze(); |
| 582 set_branch_analysis(&analysis); | 567 set_branch_analysis(&analysis); |
| 583 interpreter::BytecodeArrayIterator iterator(bytecode_array()); | 568 interpreter::BytecodeArrayIterator iterator(bytecode_array()); |
| 584 set_bytecode_iterator(&iterator); | 569 set_bytecode_iterator(&iterator); |
| 585 while (!iterator.done()) { | 570 while (!iterator.done()) { |
| 586 int current_offset = iterator.current_offset(); | 571 int current_offset = iterator.current_offset(); |
| 587 EnterAndExitExceptionHandlers(current_offset); | 572 EnterAndExitExceptionHandlers(current_offset); |
| 588 SwitchToMergeEnvironment(current_offset); | 573 SwitchToMergeEnvironment(current_offset); |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 } | 1499 } |
| 1515 | 1500 |
| 1516 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() { | 1501 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() { |
| 1517 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); | 1502 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); |
| 1518 } | 1503 } |
| 1519 | 1504 |
| 1520 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() { | 1505 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() { |
| 1521 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); | 1506 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); |
| 1522 } | 1507 } |
| 1523 | 1508 |
| 1509 void BytecodeGraphBuilder::VisitStackCheck() { |
| 1510 FrameStateBeforeAndAfter states(this); |
| 1511 Node* node = NewNode(javascript()->StackCheck()); |
| 1512 environment()->RecordAfterState(node, &states); |
| 1513 } |
| 1514 |
| 1524 void BytecodeGraphBuilder::VisitReturn() { | 1515 void BytecodeGraphBuilder::VisitReturn() { |
| 1525 Node* control = | 1516 Node* control = |
| 1526 NewNode(common()->Return(), environment()->LookupAccumulator()); | 1517 NewNode(common()->Return(), environment()->LookupAccumulator()); |
| 1527 MergeControlToLeaveFunction(control); | 1518 MergeControlToLeaveFunction(control); |
| 1528 } | 1519 } |
| 1529 | 1520 |
| 1530 void BytecodeGraphBuilder::BuildForInPrepare() { | 1521 void BytecodeGraphBuilder::BuildForInPrepare() { |
| 1531 FrameStateBeforeAndAfter states(this); | 1522 FrameStateBeforeAndAfter states(this); |
| 1532 Node* receiver = environment()->LookupAccumulator(); | 1523 Node* receiver = environment()->LookupAccumulator(); |
| 1533 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver); | 1524 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 while (current_exception_handler_ < num_entries) { | 1661 while (current_exception_handler_ < num_entries) { |
| 1671 int next_start = table->GetRangeStart(current_exception_handler_); | 1662 int next_start = table->GetRangeStart(current_exception_handler_); |
| 1672 if (current_offset < next_start) break; // Not yet covered by range. | 1663 if (current_offset < next_start) break; // Not yet covered by range. |
| 1673 int next_end = table->GetRangeEnd(current_exception_handler_); | 1664 int next_end = table->GetRangeEnd(current_exception_handler_); |
| 1674 int next_handler = table->GetRangeHandler(current_exception_handler_); | 1665 int next_handler = table->GetRangeHandler(current_exception_handler_); |
| 1675 exception_handlers_.push({next_start, next_end, next_handler}); | 1666 exception_handlers_.push({next_start, next_end, next_handler}); |
| 1676 current_exception_handler_++; | 1667 current_exception_handler_++; |
| 1677 } | 1668 } |
| 1678 } | 1669 } |
| 1679 | 1670 |
| 1680 void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) { | |
| 1681 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); | |
| 1682 DCHECK_EQ(IrOpcode::kDead, | |
| 1683 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | |
| 1684 NodeProperties::ReplaceFrameStateInput( | |
| 1685 node, 0, environment()->Checkpoint(BailoutId(0), | |
| 1686 OutputFrameStateCombine::Ignore())); | |
| 1687 } | |
| 1688 | |
| 1689 | |
| 1690 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 1671 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
| 1691 Node** value_inputs, bool incomplete) { | 1672 Node** value_inputs, bool incomplete) { |
| 1692 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 1673 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
| 1693 | 1674 |
| 1694 bool has_context = OperatorProperties::HasContextInput(op); | 1675 bool has_context = OperatorProperties::HasContextInput(op); |
| 1695 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op); | 1676 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op); |
| 1696 bool has_control = op->ControlInputCount() == 1; | 1677 bool has_control = op->ControlInputCount() == 1; |
| 1697 bool has_effect = op->EffectInputCount() == 1; | 1678 bool has_effect = op->EffectInputCount() == 1; |
| 1698 | 1679 |
| 1699 DCHECK_LT(op->ControlInputCount(), 2); | 1680 DCHECK_LT(op->ControlInputCount(), 2); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 // Phi does not exist yet, introduce one. | 1815 // Phi does not exist yet, introduce one. |
| 1835 value = NewPhi(inputs, value, control); | 1816 value = NewPhi(inputs, value, control); |
| 1836 value->ReplaceInput(inputs - 1, other); | 1817 value->ReplaceInput(inputs - 1, other); |
| 1837 } | 1818 } |
| 1838 return value; | 1819 return value; |
| 1839 } | 1820 } |
| 1840 | 1821 |
| 1841 } // namespace compiler | 1822 } // namespace compiler |
| 1842 } // namespace internal | 1823 } // namespace internal |
| 1843 } // namespace v8 | 1824 } // namespace v8 |
| OLD | NEW |