| 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 |