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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 break; | 716 break; |
717 case IrOpcode::kPlainPrimitiveToNumber: | 717 case IrOpcode::kPlainPrimitiveToNumber: |
718 state = LowerPlainPrimitiveToNumber(node, *effect, *control); | 718 state = LowerPlainPrimitiveToNumber(node, *effect, *control); |
719 break; | 719 break; |
720 case IrOpcode::kPlainPrimitiveToWord32: | 720 case IrOpcode::kPlainPrimitiveToWord32: |
721 state = LowerPlainPrimitiveToWord32(node, *effect, *control); | 721 state = LowerPlainPrimitiveToWord32(node, *effect, *control); |
722 break; | 722 break; |
723 case IrOpcode::kPlainPrimitiveToFloat64: | 723 case IrOpcode::kPlainPrimitiveToFloat64: |
724 state = LowerPlainPrimitiveToFloat64(node, *effect, *control); | 724 state = LowerPlainPrimitiveToFloat64(node, *effect, *control); |
725 break; | 725 break; |
| 726 case IrOpcode::kEnsureWritableFastElements: |
| 727 state = LowerEnsureWritableFastElements(node, *effect, *control); |
| 728 break; |
726 case IrOpcode::kTransitionElementsKind: | 729 case IrOpcode::kTransitionElementsKind: |
727 state = LowerTransitionElementsKind(node, *effect, *control); | 730 state = LowerTransitionElementsKind(node, *effect, *control); |
728 break; | 731 break; |
729 case IrOpcode::kLoadTypedElement: | 732 case IrOpcode::kLoadTypedElement: |
730 state = LowerLoadTypedElement(node, *effect, *control); | 733 state = LowerLoadTypedElement(node, *effect, *control); |
731 break; | 734 break; |
732 case IrOpcode::kStoreTypedElement: | 735 case IrOpcode::kStoreTypedElement: |
733 state = LowerStoreTypedElement(node, *effect, *control); | 736 state = LowerStoreTypedElement(node, *effect, *control); |
734 break; | 737 break; |
735 case IrOpcode::kFloat64RoundUp: | 738 case IrOpcode::kFloat64RoundUp: |
(...skipping 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2593 } | 2596 } |
2594 | 2597 |
2595 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 2598 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
2596 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 2599 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
2597 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 2600 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
2598 vtrue0, vfalse0, control); | 2601 vtrue0, vfalse0, control); |
2599 return ValueEffectControl(value, effect, control); | 2602 return ValueEffectControl(value, effect, control); |
2600 } | 2603 } |
2601 | 2604 |
2602 EffectControlLinearizer::ValueEffectControl | 2605 EffectControlLinearizer::ValueEffectControl |
| 2606 EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node, |
| 2607 Node* effect, |
| 2608 Node* control) { |
| 2609 Node* object = node->InputAt(0); |
| 2610 Node* elements = node->InputAt(1); |
| 2611 |
| 2612 // Load the current map of {elements}. |
| 2613 Node* elements_map = effect = |
| 2614 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 2615 elements, effect, control); |
| 2616 |
| 2617 // Check if {elements} is not a copy-on-write FixedArray. |
| 2618 Node* check = graph()->NewNode(machine()->WordEqual(), elements_map, |
| 2619 jsgraph()->FixedArrayMapConstant()); |
| 2620 Node* branch = |
| 2621 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 2622 |
| 2623 // Nothing to do if the {elements} are not copy-on-write. |
| 2624 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 2625 Node* etrue = effect; |
| 2626 Node* vtrue = elements; |
| 2627 |
| 2628 // We need to take a copy of the {elements} and set them up for {object}. |
| 2629 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 2630 Node* efalse = effect; |
| 2631 Node* vfalse; |
| 2632 { |
| 2633 // We need to create a copy of the {elements} for {object}. |
| 2634 Operator::Properties properties = Operator::kEliminatable; |
| 2635 Callable callable = CodeFactory::CopyFixedArray(isolate()); |
| 2636 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
| 2637 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
| 2638 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 2639 properties); |
| 2640 vfalse = efalse = graph()->NewNode( |
| 2641 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
| 2642 elements, jsgraph()->NoContextConstant(), efalse); |
| 2643 |
| 2644 // Store the new {elements} into {object}. |
| 2645 efalse = graph()->NewNode( |
| 2646 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), object, |
| 2647 vfalse, efalse, if_false); |
| 2648 } |
| 2649 |
| 2650 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 2651 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 2652 Node* value = graph()->NewNode( |
| 2653 common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control); |
| 2654 |
| 2655 return ValueEffectControl(value, effect, control); |
| 2656 } |
| 2657 |
| 2658 EffectControlLinearizer::ValueEffectControl |
2603 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, | 2659 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, |
2604 Node* control) { | 2660 Node* control) { |
2605 ElementsTransition const transition = ElementsTransitionOf(node->op()); | 2661 ElementsTransition const transition = ElementsTransitionOf(node->op()); |
2606 Node* object = node->InputAt(0); | 2662 Node* object = node->InputAt(0); |
2607 Node* source_map = node->InputAt(1); | 2663 Node* source_map = node->InputAt(1); |
2608 Node* target_map = node->InputAt(2); | 2664 Node* target_map = node->InputAt(2); |
2609 | 2665 |
2610 // Load the current map of {object}. | 2666 // Load the current map of {object}. |
2611 Node* object_map = effect = | 2667 Node* object_map = effect = |
2612 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, | 2668 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3111 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3167 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3112 Operator::kNoThrow); | 3168 Operator::kNoThrow); |
3113 to_number_operator_.set(common()->Call(desc)); | 3169 to_number_operator_.set(common()->Call(desc)); |
3114 } | 3170 } |
3115 return to_number_operator_.get(); | 3171 return to_number_operator_.get(); |
3116 } | 3172 } |
3117 | 3173 |
3118 } // namespace compiler | 3174 } // namespace compiler |
3119 } // namespace internal | 3175 } // namespace internal |
3120 } // namespace v8 | 3176 } // namespace v8 |
OLD | NEW |