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 default: | 738 default: |
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 } | 2587 } |
2585 | 2588 |
2586 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 2589 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
2587 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 2590 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
2588 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 2591 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
2589 vtrue0, vfalse0, control); | 2592 vtrue0, vfalse0, control); |
2590 return ValueEffectControl(value, effect, control); | 2593 return ValueEffectControl(value, effect, control); |
2591 } | 2594 } |
2592 | 2595 |
2593 EffectControlLinearizer::ValueEffectControl | 2596 EffectControlLinearizer::ValueEffectControl |
| 2597 EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node, |
| 2598 Node* effect, |
| 2599 Node* control) { |
| 2600 Node* object = node->InputAt(0); |
| 2601 Node* elements = node->InputAt(1); |
| 2602 |
| 2603 // Load the current map of {elements}. |
| 2604 Node* elements_map = effect = |
| 2605 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 2606 elements, effect, control); |
| 2607 |
| 2608 // Check if {elements} is not a copy-on-write FixedArray. |
| 2609 Node* check = graph()->NewNode(machine()->WordEqual(), elements_map, |
| 2610 jsgraph()->FixedArrayMapConstant()); |
| 2611 Node* branch = |
| 2612 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 2613 |
| 2614 // Nothing to do if the {elements} are not copy-on-write. |
| 2615 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 2616 Node* etrue = effect; |
| 2617 Node* vtrue = elements; |
| 2618 |
| 2619 // We need to take a copy of the {elements} and set them up for {object}. |
| 2620 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 2621 Node* efalse = effect; |
| 2622 Node* vfalse; |
| 2623 { |
| 2624 // We need to create a copy of the {elements} for {object}. |
| 2625 Operator::Properties properties = Operator::kEliminatable; |
| 2626 Callable callable = CodeFactory::CopyFixedArray(isolate()); |
| 2627 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
| 2628 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
| 2629 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 2630 properties); |
| 2631 vfalse = efalse = graph()->NewNode( |
| 2632 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
| 2633 elements, jsgraph()->NoContextConstant(), efalse); |
| 2634 |
| 2635 // Store the new {elements} into {object}. |
| 2636 efalse = graph()->NewNode( |
| 2637 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), object, |
| 2638 vfalse, efalse, if_false); |
| 2639 } |
| 2640 |
| 2641 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 2642 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 2643 Node* value = graph()->NewNode( |
| 2644 common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control); |
| 2645 |
| 2646 return ValueEffectControl(value, effect, control); |
| 2647 } |
| 2648 |
| 2649 EffectControlLinearizer::ValueEffectControl |
2594 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, | 2650 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, |
2595 Node* control) { | 2651 Node* control) { |
2596 ElementsTransition const transition = ElementsTransitionOf(node->op()); | 2652 ElementsTransition const transition = ElementsTransitionOf(node->op()); |
2597 Node* object = node->InputAt(0); | 2653 Node* object = node->InputAt(0); |
2598 Node* source_map = node->InputAt(1); | 2654 Node* source_map = node->InputAt(1); |
2599 Node* target_map = node->InputAt(2); | 2655 Node* target_map = node->InputAt(2); |
2600 | 2656 |
2601 // Load the current map of {object}. | 2657 // Load the current map of {object}. |
2602 Node* object_map = effect = | 2658 Node* object_map = effect = |
2603 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, | 2659 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2718 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 2774 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
2719 Operator::kNoThrow); | 2775 Operator::kNoThrow); |
2720 to_number_operator_.set(common()->Call(desc)); | 2776 to_number_operator_.set(common()->Call(desc)); |
2721 } | 2777 } |
2722 return to_number_operator_.get(); | 2778 return to_number_operator_.get(); |
2723 } | 2779 } |
2724 | 2780 |
2725 } // namespace compiler | 2781 } // namespace compiler |
2726 } // namespace internal | 2782 } // namespace internal |
2727 } // namespace v8 | 2783 } // namespace v8 |
OLD | NEW |