| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 output_poke_offset_(0), | 106 output_poke_offset_(0), |
| 107 output_poke_count_(0) { | 107 output_poke_count_(0) { |
| 108 BailoutId id_before(builder->bytecode_iterator().current_offset()); | 108 BailoutId id_before(builder->bytecode_iterator().current_offset()); |
| 109 frame_state_before_ = builder_->environment()->Checkpoint( | 109 frame_state_before_ = builder_->environment()->Checkpoint( |
| 110 id_before, OutputFrameStateCombine::Ignore()); | 110 id_before, OutputFrameStateCombine::Ignore()); |
| 111 id_after_ = BailoutId(id_before.ToInt() + | 111 id_after_ = BailoutId(id_before.ToInt() + |
| 112 builder->bytecode_iterator().current_bytecode_size()); | 112 builder->bytecode_iterator().current_bytecode_size()); |
| 113 // Create an explicit checkpoint node for before the operation. | 113 // Create an explicit checkpoint node for before the operation. |
| 114 Node* node = builder_->NewNode(builder_->common()->Checkpoint()); | 114 Node* node = builder_->NewNode(builder_->common()->Checkpoint()); |
| 115 DCHECK_EQ(IrOpcode::kDead, | 115 DCHECK_EQ(IrOpcode::kDead, |
| 116 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 116 NodeProperties::GetFrameStateInput(node)->opcode()); |
| 117 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_before_); | 117 NodeProperties::ReplaceFrameStateInput(node, frame_state_before_); |
| 118 } | 118 } |
| 119 | 119 |
| 120 ~FrameStateBeforeAndAfter() { | 120 ~FrameStateBeforeAndAfter() { |
| 121 DCHECK(added_to_node_); | 121 DCHECK(added_to_node_); |
| 122 DCHECK(frame_states_unused_ || | 122 DCHECK(frame_states_unused_ || |
| 123 builder_->environment()->StateValuesAreUpToDate(output_poke_offset_, | 123 builder_->environment()->StateValuesAreUpToDate(output_poke_offset_, |
| 124 output_poke_count_)); | 124 output_poke_count_)); |
| 125 } | 125 } |
| 126 | 126 |
| 127 private: | 127 private: |
| 128 friend class Environment; | 128 friend class Environment; |
| 129 | 129 |
| 130 void AddToNode(Node* node, OutputFrameStateCombine combine) { | 130 void AddToNode(Node* node, OutputFrameStateCombine combine) { |
| 131 DCHECK(!added_to_node_); | 131 DCHECK(!added_to_node_); |
| 132 int count = OperatorProperties::GetFrameStateInputCount(node->op()); | 132 bool has_frame_state = OperatorProperties::HasFrameStateInput(node->op()); |
| 133 DCHECK_LE(count, 2); | 133 if (has_frame_state) { |
| 134 if (count >= 1) { | |
| 135 // Add the frame state for after the operation. | 134 // Add the frame state for after the operation. |
| 136 DCHECK_EQ(IrOpcode::kDead, | 135 DCHECK_EQ(IrOpcode::kDead, |
| 137 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 136 NodeProperties::GetFrameStateInput(node)->opcode()); |
| 138 Node* frame_state_after = | 137 Node* frame_state_after = |
| 139 builder_->environment()->Checkpoint(id_after_, combine); | 138 builder_->environment()->Checkpoint(id_after_, combine); |
| 140 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); | 139 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); |
| 141 } | |
| 142 | |
| 143 if (count >= 2) { | |
| 144 // Add the frame state for before the operation. | |
| 145 // TODO(mstarzinger): Get rid of frame state input before! | |
| 146 DCHECK_EQ(IrOpcode::kDead, | |
| 147 NodeProperties::GetFrameStateInput(node, 1)->opcode()); | |
| 148 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_); | |
| 149 } | 140 } |
| 150 | 141 |
| 151 if (!combine.IsOutputIgnored()) { | 142 if (!combine.IsOutputIgnored()) { |
| 152 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt()); | 143 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt()); |
| 153 output_poke_count_ = node->op()->ValueOutputCount(); | 144 output_poke_count_ = node->op()->ValueOutputCount(); |
| 154 } | 145 } |
| 155 frame_states_unused_ = count == 0; | 146 frame_states_unused_ = !has_frame_state; |
| 156 added_to_node_ = true; | 147 added_to_node_ = true; |
| 157 } | 148 } |
| 158 | 149 |
| 159 BytecodeGraphBuilder* builder_; | 150 BytecodeGraphBuilder* builder_; |
| 160 Node* frame_state_before_; | 151 Node* frame_state_before_; |
| 161 BailoutId id_after_; | 152 BailoutId id_after_; |
| 162 | 153 |
| 163 bool added_to_node_; | 154 bool added_to_node_; |
| 164 bool frame_states_unused_; | 155 bool frame_states_unused_; |
| 165 int output_poke_offset_; | 156 int output_poke_offset_; |
| (...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 {next_start, next_end, next_handler, context_register}); | 1665 {next_start, next_end, next_handler, context_register}); |
| 1675 current_exception_handler_++; | 1666 current_exception_handler_++; |
| 1676 } | 1667 } |
| 1677 } | 1668 } |
| 1678 | 1669 |
| 1679 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, | 1670 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, |
| 1680 Node** value_inputs, bool incomplete) { | 1671 Node** value_inputs, bool incomplete) { |
| 1681 DCHECK_EQ(op->ValueInputCount(), value_input_count); | 1672 DCHECK_EQ(op->ValueInputCount(), value_input_count); |
| 1682 | 1673 |
| 1683 bool has_context = OperatorProperties::HasContextInput(op); | 1674 bool has_context = OperatorProperties::HasContextInput(op); |
| 1684 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op); | 1675 bool has_frame_state = OperatorProperties::HasFrameStateInput(op); |
| 1685 bool has_control = op->ControlInputCount() == 1; | 1676 bool has_control = op->ControlInputCount() == 1; |
| 1686 bool has_effect = op->EffectInputCount() == 1; | 1677 bool has_effect = op->EffectInputCount() == 1; |
| 1687 | 1678 |
| 1688 DCHECK_LT(op->ControlInputCount(), 2); | 1679 DCHECK_LT(op->ControlInputCount(), 2); |
| 1689 DCHECK_LT(op->EffectInputCount(), 2); | 1680 DCHECK_LT(op->EffectInputCount(), 2); |
| 1690 | 1681 |
| 1691 Node* result = nullptr; | 1682 Node* result = nullptr; |
| 1692 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) { | 1683 if (!has_context && !has_frame_state && !has_control && !has_effect) { |
| 1693 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); | 1684 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); |
| 1694 } else { | 1685 } else { |
| 1695 bool inside_handler = !exception_handlers_.empty(); | 1686 bool inside_handler = !exception_handlers_.empty(); |
| 1696 int input_count_with_deps = value_input_count; | 1687 int input_count_with_deps = value_input_count; |
| 1697 if (has_context) ++input_count_with_deps; | 1688 if (has_context) ++input_count_with_deps; |
| 1698 input_count_with_deps += frame_state_count; | 1689 if (has_frame_state) ++input_count_with_deps; |
| 1699 if (has_control) ++input_count_with_deps; | 1690 if (has_control) ++input_count_with_deps; |
| 1700 if (has_effect) ++input_count_with_deps; | 1691 if (has_effect) ++input_count_with_deps; |
| 1701 Node** buffer = EnsureInputBufferSize(input_count_with_deps); | 1692 Node** buffer = EnsureInputBufferSize(input_count_with_deps); |
| 1702 memcpy(buffer, value_inputs, kPointerSize * value_input_count); | 1693 memcpy(buffer, value_inputs, kPointerSize * value_input_count); |
| 1703 Node** current_input = buffer + value_input_count; | 1694 Node** current_input = buffer + value_input_count; |
| 1704 if (has_context) { | 1695 if (has_context) { |
| 1705 *current_input++ = environment()->Context(); | 1696 *current_input++ = environment()->Context(); |
| 1706 } | 1697 } |
| 1707 for (int i = 0; i < frame_state_count; i++) { | 1698 if (has_frame_state) { |
| 1708 // The frame state will be inserted later. Here we misuse | 1699 // The frame state will be inserted later. Here we misuse |
| 1709 // the {Dead} node as a sentinel to be later overwritten | 1700 // the {Dead} node as a sentinel to be later overwritten |
| 1710 // with the real frame state. | 1701 // with the real frame state. |
| 1711 *current_input++ = jsgraph()->Dead(); | 1702 *current_input++ = jsgraph()->Dead(); |
| 1712 } | 1703 } |
| 1713 if (has_effect) { | 1704 if (has_effect) { |
| 1714 *current_input++ = environment()->GetEffectDependency(); | 1705 *current_input++ = environment()->GetEffectDependency(); |
| 1715 } | 1706 } |
| 1716 if (has_control) { | 1707 if (has_control) { |
| 1717 *current_input++ = environment()->GetControlDependency(); | 1708 *current_input++ = environment()->GetControlDependency(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1825 // Phi does not exist yet, introduce one. | 1816 // Phi does not exist yet, introduce one. |
| 1826 value = NewPhi(inputs, value, control); | 1817 value = NewPhi(inputs, value, control); |
| 1827 value->ReplaceInput(inputs - 1, other); | 1818 value->ReplaceInput(inputs - 1, other); |
| 1828 } | 1819 } |
| 1829 return value; | 1820 return value; |
| 1830 } | 1821 } |
| 1831 | 1822 |
| 1832 } // namespace compiler | 1823 } // namespace compiler |
| 1833 } // namespace internal | 1824 } // namespace internal |
| 1834 } // namespace v8 | 1825 } // namespace v8 |
| OLD | NEW |