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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 break; | 699 break; |
700 case IrOpcode::kPlainPrimitiveToNumber: | 700 case IrOpcode::kPlainPrimitiveToNumber: |
701 state = LowerPlainPrimitiveToNumber(node, *effect, *control); | 701 state = LowerPlainPrimitiveToNumber(node, *effect, *control); |
702 break; | 702 break; |
703 case IrOpcode::kPlainPrimitiveToWord32: | 703 case IrOpcode::kPlainPrimitiveToWord32: |
704 state = LowerPlainPrimitiveToWord32(node, *effect, *control); | 704 state = LowerPlainPrimitiveToWord32(node, *effect, *control); |
705 break; | 705 break; |
706 case IrOpcode::kPlainPrimitiveToFloat64: | 706 case IrOpcode::kPlainPrimitiveToFloat64: |
707 state = LowerPlainPrimitiveToFloat64(node, *effect, *control); | 707 state = LowerPlainPrimitiveToFloat64(node, *effect, *control); |
708 break; | 708 break; |
| 709 case IrOpcode::kTransitionElementsKind: |
| 710 state = LowerTransitionElementsKind(node, *effect, *control); |
| 711 break; |
709 default: | 712 default: |
710 return false; | 713 return false; |
711 } | 714 } |
712 NodeProperties::ReplaceUses(node, state.value, state.effect, state.control); | 715 NodeProperties::ReplaceUses(node, state.value, state.effect, state.control); |
713 *effect = state.effect; | 716 *effect = state.effect; |
714 *control = state.control; | 717 *control = state.control; |
715 return true; | 718 return true; |
716 } | 719 } |
717 | 720 |
718 EffectControlLinearizer::ValueEffectControl | 721 EffectControlLinearizer::ValueEffectControl |
(...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2114 vtrue1, vfalse1, if_false0); | 2117 vtrue1, vfalse1, if_false0); |
2115 } | 2118 } |
2116 | 2119 |
2117 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 2120 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
2118 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 2121 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
2119 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 2122 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
2120 vtrue0, vfalse0, control); | 2123 vtrue0, vfalse0, control); |
2121 return ValueEffectControl(value, effect, control); | 2124 return ValueEffectControl(value, effect, control); |
2122 } | 2125 } |
2123 | 2126 |
| 2127 EffectControlLinearizer::ValueEffectControl |
| 2128 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, |
| 2129 Node* control) { |
| 2130 ElementsTransition const transition = ElementsTransitionOf(node->op()); |
| 2131 Node* object = node->InputAt(0); |
| 2132 Node* source_map = node->InputAt(1); |
| 2133 Node* target_map = node->InputAt(2); |
| 2134 |
| 2135 // Load the current map of {object}. |
| 2136 Node* object_map = effect = |
| 2137 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, |
| 2138 effect, control); |
| 2139 |
| 2140 // Check if {object_map} is the same as {source_map}. |
| 2141 Node* check = |
| 2142 graph()->NewNode(machine()->WordEqual(), object_map, source_map); |
| 2143 Node* branch = |
| 2144 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 2145 |
| 2146 // Migrate the {object} from {source_map} to {target_map}. |
| 2147 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 2148 Node* etrue = effect; |
| 2149 { |
| 2150 switch (transition) { |
| 2151 case ElementsTransition::kFastTransition: { |
| 2152 // In-place migration of {object}, just store the {target_map}. |
| 2153 etrue = |
| 2154 graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
| 2155 object, target_map, etrue, if_true); |
| 2156 break; |
| 2157 } |
| 2158 case ElementsTransition::kSlowTransition: { |
| 2159 // Instance migration, call out to the runtime for {object}. |
| 2160 Operator::Properties properties = |
| 2161 Operator::kNoDeopt | Operator::kNoThrow; |
| 2162 Runtime::FunctionId id = Runtime::kTransitionElementsKind; |
| 2163 CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( |
| 2164 graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags); |
| 2165 etrue = graph()->NewNode( |
| 2166 common()->Call(desc), jsgraph()->CEntryStubConstant(1), object, |
| 2167 target_map, |
| 2168 jsgraph()->ExternalConstant(ExternalReference(id, isolate())), |
| 2169 jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(), etrue, |
| 2170 if_true); |
| 2171 break; |
| 2172 } |
| 2173 } |
| 2174 } |
| 2175 |
| 2176 // Nothing to do if the {object} doesn't have the {source_map}. |
| 2177 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 2178 Node* efalse = effect; |
| 2179 |
| 2180 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 2181 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 2182 |
| 2183 return ValueEffectControl(nullptr, effect, control); |
| 2184 } |
| 2185 |
2124 Factory* EffectControlLinearizer::factory() const { | 2186 Factory* EffectControlLinearizer::factory() const { |
2125 return isolate()->factory(); | 2187 return isolate()->factory(); |
2126 } | 2188 } |
2127 | 2189 |
2128 Isolate* EffectControlLinearizer::isolate() const { | 2190 Isolate* EffectControlLinearizer::isolate() const { |
2129 return jsgraph()->isolate(); | 2191 return jsgraph()->isolate(); |
2130 } | 2192 } |
2131 | 2193 |
2132 Operator const* EffectControlLinearizer::ToNumberOperator() { | 2194 Operator const* EffectControlLinearizer::ToNumberOperator() { |
2133 if (!to_number_operator_.is_set()) { | 2195 if (!to_number_operator_.is_set()) { |
2134 Callable callable = CodeFactory::ToNumber(isolate()); | 2196 Callable callable = CodeFactory::ToNumber(isolate()); |
2135 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 2197 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
2136 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 2198 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
2137 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 2199 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
2138 Operator::kNoThrow); | 2200 Operator::kNoThrow); |
2139 to_number_operator_.set(common()->Call(desc)); | 2201 to_number_operator_.set(common()->Call(desc)); |
2140 } | 2202 } |
2141 return to_number_operator_.get(); | 2203 return to_number_operator_.get(); |
2142 } | 2204 } |
2143 | 2205 |
2144 } // namespace compiler | 2206 } // namespace compiler |
2145 } // namespace internal | 2207 } // namespace internal |
2146 } // namespace v8 | 2208 } // namespace v8 |
OLD | NEW |