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/js-call-reducer.h" | 5 #include "src/compiler/js-call-reducer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.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" |
11 #include "src/compiler/js-graph.h" | 11 #include "src/compiler/js-graph.h" |
12 #include "src/compiler/linkage.h" | 12 #include "src/compiler/linkage.h" |
13 #include "src/compiler/node-matchers.h" | 13 #include "src/compiler/node-matchers.h" |
14 #include "src/compiler/simplified-operator.h" | 14 #include "src/compiler/simplified-operator.h" |
15 #include "src/feedback-vector-inl.h" | 15 #include "src/feedback-vector-inl.h" |
16 #include "src/ic/call-optimization.h" | 16 #include "src/ic/call-optimization.h" |
17 #include "src/objects-inl.h" | 17 #include "src/objects-inl.h" |
18 | 18 |
19 namespace v8 { | 19 namespace v8 { |
20 namespace internal { | 20 namespace internal { |
21 namespace compiler { | 21 namespace compiler { |
22 | 22 |
23 Reduction JSCallReducer::Reduce(Node* node) { | 23 Reduction JSCallReducer::Reduce(Node* node) { |
24 switch (node->opcode()) { | 24 switch (node->opcode()) { |
25 case IrOpcode::kJSConstruct: | 25 case IrOpcode::kJSConstruct: |
26 return ReduceJSConstruct(node); | 26 return ReduceJSConstruct(node); |
| 27 case IrOpcode::kJSConstructWithArrayLike: |
| 28 return ReduceJSConstructWithArrayLike(node); |
27 case IrOpcode::kJSConstructWithSpread: | 29 case IrOpcode::kJSConstructWithSpread: |
28 return ReduceJSConstructWithSpread(node); | 30 return ReduceJSConstructWithSpread(node); |
29 case IrOpcode::kJSCall: | 31 case IrOpcode::kJSCall: |
30 return ReduceJSCall(node); | 32 return ReduceJSCall(node); |
31 case IrOpcode::kJSCallWithArrayLike: | 33 case IrOpcode::kJSCallWithArrayLike: |
32 return ReduceJSCallWithArrayLike(node); | 34 return ReduceJSCallWithArrayLike(node); |
33 case IrOpcode::kJSCallWithSpread: | 35 case IrOpcode::kJSCallWithSpread: |
34 return ReduceJSCallWithSpread(node); | 36 return ReduceJSCallWithSpread(node); |
35 default: | 37 default: |
36 break; | 38 break; |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 } | 431 } |
430 while (arity-- > 3) { | 432 while (arity-- > 3) { |
431 node->RemoveInput(arity); | 433 node->RemoveInput(arity); |
432 } | 434 } |
433 NodeProperties::ChangeOp(node, | 435 NodeProperties::ChangeOp(node, |
434 javascript()->CallWithArrayLike(p.frequency())); | 436 javascript()->CallWithArrayLike(p.frequency())); |
435 Reduction const reduction = ReduceJSCallWithArrayLike(node); | 437 Reduction const reduction = ReduceJSCallWithArrayLike(node); |
436 return reduction.Changed() ? reduction : Changed(node); | 438 return reduction.Changed() ? reduction : Changed(node); |
437 } | 439 } |
438 | 440 |
| 441 // ES6 section 26.1.2 Reflect.construct ( target, argumentsList [, newTarget] ) |
| 442 Reduction JSCallReducer::ReduceReflectConstruct(Node* node) { |
| 443 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 444 CallParameters const& p = CallParametersOf(node->op()); |
| 445 int arity = static_cast<int>(p.arity() - 2); |
| 446 DCHECK_LE(0, arity); |
| 447 // Massage value inputs appropriately. |
| 448 node->RemoveInput(0); |
| 449 node->RemoveInput(0); |
| 450 while (arity < 2) { |
| 451 node->InsertInput(graph()->zone(), arity++, jsgraph()->UndefinedConstant()); |
| 452 } |
| 453 if (arity < 3) { |
| 454 node->InsertInput(graph()->zone(), arity++, node->InputAt(0)); |
| 455 } |
| 456 while (arity-- > 3) { |
| 457 node->RemoveInput(arity); |
| 458 } |
| 459 NodeProperties::ChangeOp(node, |
| 460 javascript()->ConstructWithArrayLike(p.frequency())); |
| 461 Reduction const reduction = ReduceJSConstructWithArrayLike(node); |
| 462 return reduction.Changed() ? reduction : Changed(node); |
| 463 } |
| 464 |
439 // ES6 section 26.1.7 Reflect.getPrototypeOf ( target ) | 465 // ES6 section 26.1.7 Reflect.getPrototypeOf ( target ) |
440 Reduction JSCallReducer::ReduceReflectGetPrototypeOf(Node* node) { | 466 Reduction JSCallReducer::ReduceReflectGetPrototypeOf(Node* node) { |
441 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | 467 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
442 Node* target = (node->op()->ValueInputCount() >= 3) | 468 Node* target = (node->op()->ValueInputCount() >= 3) |
443 ? NodeProperties::GetValueInput(node, 2) | 469 ? NodeProperties::GetValueInput(node, 2) |
444 : jsgraph()->UndefinedConstant(); | 470 : jsgraph()->UndefinedConstant(); |
445 return ReduceObjectGetPrototype(node, target); | 471 return ReduceObjectGetPrototype(node, target); |
446 } | 472 } |
447 | 473 |
448 Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, | 474 Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function, |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 jsgraph()->ExternalConstant(function_reference)); | 683 jsgraph()->ExternalConstant(function_reference)); |
658 node->ReplaceInput(5, receiver); | 684 node->ReplaceInput(5, receiver); |
659 NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); | 685 NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); |
660 return Changed(node); | 686 return Changed(node); |
661 } | 687 } |
662 | 688 |
663 Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread( | 689 Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread( |
664 Node* node, int arity, CallFrequency const& frequency) { | 690 Node* node, int arity, CallFrequency const& frequency) { |
665 DCHECK(node->opcode() == IrOpcode::kJSCallWithArrayLike || | 691 DCHECK(node->opcode() == IrOpcode::kJSCallWithArrayLike || |
666 node->opcode() == IrOpcode::kJSCallWithSpread || | 692 node->opcode() == IrOpcode::kJSCallWithSpread || |
| 693 node->opcode() == IrOpcode::kJSConstructWithArrayLike || |
667 node->opcode() == IrOpcode::kJSConstructWithSpread); | 694 node->opcode() == IrOpcode::kJSConstructWithSpread); |
668 | 695 |
669 // In case of a call/construct with spread, we need to | 696 // In case of a call/construct with spread, we need to |
670 // ensure that it's safe to avoid the actual iteration. | 697 // ensure that it's safe to avoid the actual iteration. |
671 if ((node->opcode() == IrOpcode::kJSCallWithSpread || | 698 if ((node->opcode() == IrOpcode::kJSCallWithSpread || |
672 node->opcode() == IrOpcode::kJSConstructWithSpread) && | 699 node->opcode() == IrOpcode::kJSConstructWithSpread) && |
673 !isolate()->initial_array_iterator_prototype_map()->is_stable()) { | 700 !isolate()->initial_array_iterator_prototype_map()->is_stable()) { |
674 return NoChange(); | 701 return NoChange(); |
675 } | 702 } |
676 | 703 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 case Builtins::kNumberConstructor: | 875 case Builtins::kNumberConstructor: |
849 return ReduceNumberConstructor(node); | 876 return ReduceNumberConstructor(node); |
850 case Builtins::kObjectGetPrototypeOf: | 877 case Builtins::kObjectGetPrototypeOf: |
851 return ReduceObjectGetPrototypeOf(node); | 878 return ReduceObjectGetPrototypeOf(node); |
852 case Builtins::kObjectPrototypeGetProto: | 879 case Builtins::kObjectPrototypeGetProto: |
853 return ReduceObjectPrototypeGetProto(node); | 880 return ReduceObjectPrototypeGetProto(node); |
854 case Builtins::kObjectPrototypeIsPrototypeOf: | 881 case Builtins::kObjectPrototypeIsPrototypeOf: |
855 return ReduceObjectPrototypeIsPrototypeOf(node); | 882 return ReduceObjectPrototypeIsPrototypeOf(node); |
856 case Builtins::kReflectApply: | 883 case Builtins::kReflectApply: |
857 return ReduceReflectApply(node); | 884 return ReduceReflectApply(node); |
| 885 case Builtins::kReflectConstruct: |
| 886 return ReduceReflectConstruct(node); |
858 case Builtins::kReflectGetPrototypeOf: | 887 case Builtins::kReflectGetPrototypeOf: |
859 return ReduceReflectGetPrototypeOf(node); | 888 return ReduceReflectGetPrototypeOf(node); |
860 case Builtins::kArrayForEach: | 889 case Builtins::kArrayForEach: |
861 return ReduceArrayForEach(function, node); | 890 return ReduceArrayForEach(function, node); |
862 case Builtins::kReturnReceiver: | 891 case Builtins::kReturnReceiver: |
863 return ReduceReturnReceiver(node); | 892 return ReduceReturnReceiver(node); |
864 default: | 893 default: |
865 break; | 894 break; |
866 } | 895 } |
867 | 896 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 | 1140 |
1112 // Try to further reduce the JSConstruct {node}. | 1141 // Try to further reduce the JSConstruct {node}. |
1113 Reduction const reduction = ReduceJSConstruct(node); | 1142 Reduction const reduction = ReduceJSConstruct(node); |
1114 return reduction.Changed() ? reduction : Changed(node); | 1143 return reduction.Changed() ? reduction : Changed(node); |
1115 } | 1144 } |
1116 } | 1145 } |
1117 | 1146 |
1118 return NoChange(); | 1147 return NoChange(); |
1119 } | 1148 } |
1120 | 1149 |
| 1150 Reduction JSCallReducer::ReduceJSConstructWithArrayLike(Node* node) { |
| 1151 DCHECK_EQ(IrOpcode::kJSConstructWithArrayLike, node->opcode()); |
| 1152 CallFrequency frequency = CallFrequencyOf(node->op()); |
| 1153 return ReduceCallOrConstructWithArrayLikeOrSpread(node, 1, frequency); |
| 1154 } |
| 1155 |
1121 Reduction JSCallReducer::ReduceJSConstructWithSpread(Node* node) { | 1156 Reduction JSCallReducer::ReduceJSConstructWithSpread(Node* node) { |
1122 DCHECK_EQ(IrOpcode::kJSConstructWithSpread, node->opcode()); | 1157 DCHECK_EQ(IrOpcode::kJSConstructWithSpread, node->opcode()); |
1123 SpreadWithArityParameter const& p = SpreadWithArityParameterOf(node->op()); | 1158 SpreadWithArityParameter const& p = SpreadWithArityParameterOf(node->op()); |
1124 DCHECK_LE(3u, p.arity()); | 1159 DCHECK_LE(3u, p.arity()); |
1125 int arity = static_cast<int>(p.arity() - 2); | 1160 int arity = static_cast<int>(p.arity() - 2); |
1126 | 1161 |
1127 // TODO(turbofan): Collect call counts on spread call/construct and thread it | 1162 // TODO(turbofan): Collect call counts on spread call/construct and thread it |
1128 // through here. | 1163 // through here. |
1129 CallFrequency frequency; | 1164 CallFrequency frequency; |
1130 return ReduceCallOrConstructWithArrayLikeOrSpread(node, arity, frequency); | 1165 return ReduceCallOrConstructWithArrayLikeOrSpread(node, arity, frequency); |
(...skipping 25 matching lines...) Expand all Loading... |
1156 return jsgraph()->javascript(); | 1191 return jsgraph()->javascript(); |
1157 } | 1192 } |
1158 | 1193 |
1159 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 1194 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
1160 return jsgraph()->simplified(); | 1195 return jsgraph()->simplified(); |
1161 } | 1196 } |
1162 | 1197 |
1163 } // namespace compiler | 1198 } // namespace compiler |
1164 } // namespace internal | 1199 } // namespace internal |
1165 } // namespace v8 | 1200 } // namespace v8 |
OLD | NEW |