OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 // Primitive store into a field. | 54 // Primitive store into a field. |
55 void Store(const FieldAccess& access, Node* value) { | 55 void Store(const FieldAccess& access, Node* value) { |
56 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, | 56 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, |
57 value, effect_, control_); | 57 value, effect_, control_); |
58 } | 58 } |
59 | 59 |
60 // Compound allocation of a FixedArray. | 60 // Compound allocation of a FixedArray. |
61 void AllocateArray(int length, Handle<Map> map) { | 61 void AllocateArray(int length, Handle<Map> map) { |
62 Allocate(FixedArray::SizeFor(length)); | 62 Allocate(FixedArray::SizeFor(length)); |
63 Store(AccessBuilder::ForMap(), map); | 63 Store(AccessBuilder::ForMap(), map); |
64 Store(AccessBuilder::ForFixedArrayLength(graph()->zone()), | 64 Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); |
65 jsgraph()->Constant(length)); | |
66 } | 65 } |
67 | 66 |
68 // Compound store of a constant into a field. | 67 // Compound store of a constant into a field. |
69 void Store(const FieldAccess& access, Handle<Object> value) { | 68 void Store(const FieldAccess& access, Handle<Object> value) { |
70 Store(access, jsgraph()->Constant(value)); | 69 Store(access, jsgraph()->Constant(value)); |
71 } | 70 } |
72 | 71 |
73 void FinishAndChange(Node* node) { | 72 void FinishAndChange(Node* node) { |
74 NodeProperties::SetType(allocation_, NodeProperties::GetType(node)); | 73 NodeProperties::SetType(allocation_, NodeProperties::GetType(node)); |
75 node->ReplaceInput(0, allocation_); | 74 node->ReplaceInput(0, allocation_); |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 return Changed(node); | 694 return Changed(node); |
696 } else if (input_type->Is(Type::OrderedNumber())) { | 695 } else if (input_type->Is(Type::OrderedNumber())) { |
697 // JSUnaryNot(x:number) => NumberEqual(x,#0) | 696 // JSUnaryNot(x:number) => NumberEqual(x,#0) |
698 RelaxEffectsAndControls(node); | 697 RelaxEffectsAndControls(node); |
699 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 698 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
700 node->TrimInputCount(2); | 699 node->TrimInputCount(2); |
701 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); | 700 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); |
702 return Changed(node); | 701 return Changed(node); |
703 } else if (input_type->Is(Type::String())) { | 702 } else if (input_type->Is(Type::String())) { |
704 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) | 703 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) |
705 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 704 FieldAccess const access = AccessBuilder::ForStringLength(); |
706 // It is safe for the load to be effect-free (i.e. not linked into effect | 705 // It is safe for the load to be effect-free (i.e. not linked into effect |
707 // chain) because we assume String::length to be immutable. | 706 // chain) because we assume String::length to be immutable. |
708 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 707 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
709 graph()->start(), graph()->start()); | 708 graph()->start(), graph()->start()); |
710 ReplaceWithValue(node, node, length); | 709 ReplaceWithValue(node, node, length); |
711 node->ReplaceInput(0, length); | 710 node->ReplaceInput(0, length); |
712 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 711 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
713 node->TrimInputCount(2); | 712 node->TrimInputCount(2); |
714 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); | 713 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); |
715 return Changed(node); | 714 return Changed(node); |
(...skipping 13 matching lines...) Expand all Loading... |
729 } else if (input_type->Is(Type::OrderedNumber())) { | 728 } else if (input_type->Is(Type::OrderedNumber())) { |
730 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) | 729 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) |
731 RelaxEffectsAndControls(node); | 730 RelaxEffectsAndControls(node); |
732 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, | 731 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, |
733 jsgraph()->ZeroConstant())); | 732 jsgraph()->ZeroConstant())); |
734 node->TrimInputCount(1); | 733 node->TrimInputCount(1); |
735 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); | 734 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
736 return Changed(node); | 735 return Changed(node); |
737 } else if (input_type->Is(Type::String())) { | 736 } else if (input_type->Is(Type::String())) { |
738 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) | 737 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) |
739 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 738 FieldAccess const access = AccessBuilder::ForStringLength(); |
740 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 739 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
741 effect, graph()->start()); | 740 effect, graph()->start()); |
742 ReplaceWithValue(node, node, length); | 741 ReplaceWithValue(node, node, length); |
743 node->ReplaceInput(0, jsgraph()->ZeroConstant()); | 742 node->ReplaceInput(0, jsgraph()->ZeroConstant()); |
744 node->ReplaceInput(1, length); | 743 node->ReplaceInput(1, length); |
745 node->TrimInputCount(2); | 744 node->TrimInputCount(2); |
746 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); | 745 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); |
747 return Changed(node); | 746 return Changed(node); |
748 } | 747 } |
749 return NoChange(); | 748 return NoChange(); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { | 847 Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { |
849 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); | 848 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); |
850 Node* receiver = NodeProperties::GetValueInput(node, 0); | 849 Node* receiver = NodeProperties::GetValueInput(node, 0); |
851 Type* receiver_type = NodeProperties::GetType(receiver); | 850 Type* receiver_type = NodeProperties::GetType(receiver); |
852 Node* effect = NodeProperties::GetEffectInput(node); | 851 Node* effect = NodeProperties::GetEffectInput(node); |
853 Node* control = NodeProperties::GetControlInput(node); | 852 Node* control = NodeProperties::GetControlInput(node); |
854 Handle<Name> name = NamedAccessOf(node->op()).name(); | 853 Handle<Name> name = NamedAccessOf(node->op()).name(); |
855 // Optimize "length" property of strings. | 854 // Optimize "length" property of strings. |
856 if (name.is_identical_to(factory()->length_string()) && | 855 if (name.is_identical_to(factory()->length_string()) && |
857 receiver_type->Is(Type::String())) { | 856 receiver_type->Is(Type::String())) { |
858 Node* value = effect = | 857 Node* value = effect = graph()->NewNode( |
859 graph()->NewNode(simplified()->LoadField( | 858 simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, |
860 AccessBuilder::ForStringLength(graph()->zone())), | 859 effect, control); |
861 receiver, effect, control); | |
862 ReplaceWithValue(node, value, effect); | 860 ReplaceWithValue(node, value, effect); |
863 return Replace(value); | 861 return Replace(value); |
864 } | 862 } |
865 return NoChange(); | 863 return NoChange(); |
866 } | 864 } |
867 | 865 |
868 | 866 |
869 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { | 867 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { |
870 Node* key = NodeProperties::GetValueInput(node, 1); | 868 Node* key = NodeProperties::GetValueInput(node, 1); |
871 Node* base = NodeProperties::GetValueInput(node, 0); | 869 Node* base = NodeProperties::GetValueInput(node, 0); |
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 Node* branch0 = | 1636 Node* branch0 = |
1639 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); | 1637 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
1640 | 1638 |
1641 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1639 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1642 Node* cache_array_true0; | 1640 Node* cache_array_true0; |
1643 Node* cache_length_true0; | 1641 Node* cache_length_true0; |
1644 Node* cache_type_true0; | 1642 Node* cache_type_true0; |
1645 Node* etrue0; | 1643 Node* etrue0; |
1646 { | 1644 { |
1647 // Enum cache case. | 1645 // Enum cache case. |
1648 Node* cache_type_enum_length = etrue0 = | 1646 Node* cache_type_enum_length = etrue0 = graph()->NewNode( |
1649 graph()->NewNode(simplified()->LoadField( | 1647 simplified()->LoadField(AccessBuilder::ForMapBitField3()), cache_type, |
1650 AccessBuilder::ForMapBitField3(graph()->zone())), | 1648 effect, if_true0); |
1651 cache_type, effect, if_true0); | |
1652 cache_length_true0 = graph()->NewNode( | 1649 cache_length_true0 = graph()->NewNode( |
1653 simplified()->NumberBitwiseAnd(), cache_type_enum_length, | 1650 simplified()->NumberBitwiseAnd(), cache_type_enum_length, |
1654 jsgraph()->Int32Constant(Map::EnumLengthBits::kMask)); | 1651 jsgraph()->Int32Constant(Map::EnumLengthBits::kMask)); |
1655 | 1652 |
1656 Node* check1 = | 1653 Node* check1 = |
1657 graph()->NewNode(machine()->Word32Equal(), cache_length_true0, | 1654 graph()->NewNode(machine()->Word32Equal(), cache_length_true0, |
1658 jsgraph()->Int32Constant(0)); | 1655 jsgraph()->Int32Constant(0)); |
1659 Node* branch1 = | 1656 Node* branch1 = |
1660 graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0); | 1657 graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0); |
1661 | 1658 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1711 cache_type_false0 = graph()->NewNode( | 1708 cache_type_false0 = graph()->NewNode( |
1712 common()->Select(kMachAnyTagged, BranchHint::kFalse), | 1709 common()->Select(kMachAnyTagged, BranchHint::kFalse), |
1713 graph()->NewNode(machine()->Uint32LessThanOrEqual(), | 1710 graph()->NewNode(machine()->Uint32LessThanOrEqual(), |
1714 receiver_instance_type, | 1711 receiver_instance_type, |
1715 jsgraph()->Uint32Constant(LAST_JS_PROXY_TYPE)), | 1712 jsgraph()->Uint32Constant(LAST_JS_PROXY_TYPE)), |
1716 jsgraph()->ZeroConstant(), // Zero indicagtes proxy. | 1713 jsgraph()->ZeroConstant(), // Zero indicagtes proxy. |
1717 jsgraph()->OneConstant()); // One means slow check. | 1714 jsgraph()->OneConstant()); // One means slow check. |
1718 | 1715 |
1719 cache_array_false0 = cache_type; | 1716 cache_array_false0 = cache_type; |
1720 cache_length_false0 = efalse0 = graph()->NewNode( | 1717 cache_length_false0 = efalse0 = graph()->NewNode( |
1721 simplified()->LoadField( | 1718 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
1722 AccessBuilder::ForFixedArrayLength(graph()->zone())), | |
1723 cache_array_false0, efalse0, if_false0); | 1719 cache_array_false0, efalse0, if_false0); |
1724 } | 1720 } |
1725 | 1721 |
1726 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 1722 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
1727 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 1723 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
1728 Node* cache_array = | 1724 Node* cache_array = |
1729 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), cache_array_true0, | 1725 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), cache_array_true0, |
1730 cache_array_false0, control); | 1726 cache_array_false0, control); |
1731 Node* cache_length = | 1727 Node* cache_length = |
1732 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), cache_length_true0, | 1728 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), cache_length_true0, |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 } | 2095 } |
2100 | 2096 |
2101 | 2097 |
2102 MachineOperatorBuilder* JSTypedLowering::machine() const { | 2098 MachineOperatorBuilder* JSTypedLowering::machine() const { |
2103 return jsgraph()->machine(); | 2099 return jsgraph()->machine(); |
2104 } | 2100 } |
2105 | 2101 |
2106 } // namespace compiler | 2102 } // namespace compiler |
2107 } // namespace internal | 2103 } // namespace internal |
2108 } // namespace v8 | 2104 } // namespace v8 |
OLD | NEW |