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 |