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/compiler/js-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 IterationKind::kValues); | 718 IterationKind::kValues); |
719 | 719 |
720 default: | 720 default: |
721 // Slow array iterators are not reduced | 721 // Slow array iterators are not reduced |
722 return NoChange(); | 722 return NoChange(); |
723 } | 723 } |
724 } | 724 } |
725 return NoChange(); | 725 return NoChange(); |
726 } | 726 } |
727 | 727 |
| 728 // ES6 section 22.1.2.2 Array.isArray ( arg ) |
| 729 Reduction JSBuiltinReducer::ReduceArrayIsArray(Node* node) { |
| 730 // We certainly know that undefined is not an array. |
| 731 if (node->op()->ValueInputCount() < 3) { |
| 732 Node* value = jsgraph()->FalseConstant(); |
| 733 ReplaceWithValue(node, value); |
| 734 return Replace(value); |
| 735 } |
| 736 Node* value = NodeProperties::GetValueInput(node, 2); |
| 737 Node* context = NodeProperties::GetContextInput(node); |
| 738 Node* frame_state = NodeProperties::GetFrameStateInput(node); |
| 739 Node* effect = NodeProperties::GetEffectInput(node); |
| 740 Node* control = NodeProperties::GetControlInput(node); |
| 741 |
| 742 int count = 0; |
| 743 Node* values[5]; |
| 744 Node* effects[5]; |
| 745 Node* controls[4]; |
| 746 |
| 747 // Check if the {value} is a Smi. |
| 748 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 749 control = |
| 750 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 751 |
| 752 // The {value} is a Smi. |
| 753 controls[count] = graph()->NewNode(common()->IfTrue(), control); |
| 754 effects[count] = effect; |
| 755 values[count] = jsgraph()->FalseConstant(); |
| 756 count++; |
| 757 |
| 758 control = graph()->NewNode(common()->IfFalse(), control); |
| 759 |
| 760 // Load the {value}s instance type. |
| 761 Node* value_map = effect = graph()->NewNode( |
| 762 simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
| 763 Node* value_instance_type = effect = graph()->NewNode( |
| 764 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
| 765 effect, control); |
| 766 |
| 767 // Check if the {value} is a JSArray. |
| 768 check = graph()->NewNode(simplified()->NumberEqual(), value_instance_type, |
| 769 jsgraph()->Constant(JS_ARRAY_TYPE)); |
| 770 control = graph()->NewNode(common()->Branch(), check, control); |
| 771 |
| 772 // The {value} is a JSArray. |
| 773 controls[count] = graph()->NewNode(common()->IfTrue(), control); |
| 774 effects[count] = effect; |
| 775 values[count] = jsgraph()->TrueConstant(); |
| 776 count++; |
| 777 |
| 778 control = graph()->NewNode(common()->IfFalse(), control); |
| 779 |
| 780 // Check if the {value} is a JSProxy. |
| 781 check = graph()->NewNode(simplified()->NumberEqual(), value_instance_type, |
| 782 jsgraph()->Constant(JS_PROXY_TYPE)); |
| 783 control = |
| 784 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 785 |
| 786 // The {value} is neither a JSArray nor a JSProxy. |
| 787 controls[count] = graph()->NewNode(common()->IfFalse(), control); |
| 788 effects[count] = effect; |
| 789 values[count] = jsgraph()->FalseConstant(); |
| 790 count++; |
| 791 |
| 792 control = graph()->NewNode(common()->IfTrue(), control); |
| 793 |
| 794 // Let the %ArrayIsArray runtime function deal with the JSProxy {value}. |
| 795 value = effect = |
| 796 graph()->NewNode(javascript()->CallRuntime(Runtime::kArrayIsArray), value, |
| 797 context, frame_state, effect, control); |
| 798 NodeProperties::SetType(value, Type::Boolean()); |
| 799 control = graph()->NewNode(common()->IfSuccess(), value); |
| 800 |
| 801 // Rewire any IfException edges on {node} to {value}. |
| 802 for (Edge edge : node->use_edges()) { |
| 803 Node* const user = edge.from(); |
| 804 if (user->opcode() == IrOpcode::kIfException) { |
| 805 edge.UpdateTo(value); |
| 806 Revisit(user); |
| 807 } |
| 808 } |
| 809 |
| 810 // The {value} is neither a JSArray nor a JSProxy. |
| 811 controls[count] = control; |
| 812 effects[count] = effect; |
| 813 values[count] = value; |
| 814 count++; |
| 815 |
| 816 control = graph()->NewNode(common()->Merge(count), count, controls); |
| 817 effects[count] = control; |
| 818 values[count] = control; |
| 819 effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects); |
| 820 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, count), |
| 821 count + 1, values); |
| 822 ReplaceWithValue(node, value, effect, control); |
| 823 return Replace(value); |
| 824 } |
| 825 |
728 // ES6 section 22.1.3.17 Array.prototype.pop ( ) | 826 // ES6 section 22.1.3.17 Array.prototype.pop ( ) |
729 Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) { | 827 Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) { |
730 Handle<Map> receiver_map; | 828 Handle<Map> receiver_map; |
731 Node* receiver = NodeProperties::GetValueInput(node, 1); | 829 Node* receiver = NodeProperties::GetValueInput(node, 1); |
732 Node* effect = NodeProperties::GetEffectInput(node); | 830 Node* effect = NodeProperties::GetEffectInput(node); |
733 Node* control = NodeProperties::GetControlInput(node); | 831 Node* control = NodeProperties::GetControlInput(node); |
734 // TODO(turbofan): Extend this to also handle fast (holey) double elements | 832 // TODO(turbofan): Extend this to also handle fast (holey) double elements |
735 // once we got the hole NaN mess sorted out in TurboFan/V8. | 833 // once we got the hole NaN mess sorted out in TurboFan/V8. |
736 if (GetMapWitness(node).ToHandle(&receiver_map) && | 834 if (GetMapWitness(node).ToHandle(&receiver_map) && |
737 CanInlineArrayResizeOperation(receiver_map) && | 835 CanInlineArrayResizeOperation(receiver_map) && |
(...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 if (!r.HasBuiltinFunctionId()) return NoChange(); | 2060 if (!r.HasBuiltinFunctionId()) return NoChange(); |
1963 switch (r.GetBuiltinFunctionId()) { | 2061 switch (r.GetBuiltinFunctionId()) { |
1964 case kArrayEntries: | 2062 case kArrayEntries: |
1965 return ReduceArrayIterator(node, IterationKind::kEntries); | 2063 return ReduceArrayIterator(node, IterationKind::kEntries); |
1966 case kArrayKeys: | 2064 case kArrayKeys: |
1967 return ReduceArrayIterator(node, IterationKind::kKeys); | 2065 return ReduceArrayIterator(node, IterationKind::kKeys); |
1968 case kArrayValues: | 2066 case kArrayValues: |
1969 return ReduceArrayIterator(node, IterationKind::kValues); | 2067 return ReduceArrayIterator(node, IterationKind::kValues); |
1970 case kArrayIteratorNext: | 2068 case kArrayIteratorNext: |
1971 return ReduceArrayIteratorNext(node); | 2069 return ReduceArrayIteratorNext(node); |
| 2070 case kArrayIsArray: |
| 2071 return ReduceArrayIsArray(node); |
1972 case kArrayPop: | 2072 case kArrayPop: |
1973 return ReduceArrayPop(node); | 2073 return ReduceArrayPop(node); |
1974 case kArrayPush: | 2074 case kArrayPush: |
1975 return ReduceArrayPush(node); | 2075 return ReduceArrayPush(node); |
1976 case kDateNow: | 2076 case kDateNow: |
1977 return ReduceDateNow(node); | 2077 return ReduceDateNow(node); |
1978 case kDateGetTime: | 2078 case kDateGetTime: |
1979 return ReduceDateGetTime(node); | 2079 return ReduceDateGetTime(node); |
1980 case kGlobalIsFinite: | 2080 case kGlobalIsFinite: |
1981 reduction = ReduceGlobalIsFinite(node); | 2081 reduction = ReduceGlobalIsFinite(node); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2178 return jsgraph()->simplified(); | 2278 return jsgraph()->simplified(); |
2179 } | 2279 } |
2180 | 2280 |
2181 JSOperatorBuilder* JSBuiltinReducer::javascript() const { | 2281 JSOperatorBuilder* JSBuiltinReducer::javascript() const { |
2182 return jsgraph()->javascript(); | 2282 return jsgraph()->javascript(); |
2183 } | 2283 } |
2184 | 2284 |
2185 } // namespace compiler | 2285 } // namespace compiler |
2186 } // namespace internal | 2286 } // namespace internal |
2187 } // namespace v8 | 2287 } // namespace v8 |
OLD | NEW |