Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: src/compiler/js-call-reducer.cc

Issue 2659623002: [turbofan] Reduce CallConstructWithSpread where iteration is not observable. (Closed)
Patch Set: Change test to make sure code is de-opt'd, not just never-opt'd Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-call-reducer.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/compiler/js-graph.h" 10 #include "src/compiler/js-graph.h"
10 #include "src/compiler/linkage.h" 11 #include "src/compiler/linkage.h"
11 #include "src/compiler/node-matchers.h" 12 #include "src/compiler/node-matchers.h"
12 #include "src/compiler/simplified-operator.h" 13 #include "src/compiler/simplified-operator.h"
13 #include "src/objects-inl.h" 14 #include "src/objects-inl.h"
14 #include "src/type-feedback-vector-inl.h" 15 #include "src/type-feedback-vector-inl.h"
15 16
16 namespace v8 { 17 namespace v8 {
17 namespace internal { 18 namespace internal {
18 namespace compiler { 19 namespace compiler {
19 20
20 Reduction JSCallReducer::Reduce(Node* node) { 21 Reduction JSCallReducer::Reduce(Node* node) {
21 switch (node->opcode()) { 22 switch (node->opcode()) {
22 case IrOpcode::kJSCallConstruct: 23 case IrOpcode::kJSCallConstruct:
23 return ReduceJSCallConstruct(node); 24 return ReduceJSCallConstruct(node);
25 case IrOpcode::kJSCallConstructWithSpread:
26 return ReduceJSCallConstructWithSpread(node);
24 case IrOpcode::kJSCallFunction: 27 case IrOpcode::kJSCallFunction:
25 return ReduceJSCallFunction(node); 28 return ReduceJSCallFunction(node);
26 default: 29 default:
27 break; 30 break;
28 } 31 }
29 return NoChange(); 32 return NoChange();
30 } 33 }
31 34
32 35
33 // ES6 section 22.1.1 The Array Constructor 36 // ES6 section 22.1.1 The Array Constructor
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 687
685 // Try to further reduce the JSCallConstruct {node}. 688 // Try to further reduce the JSCallConstruct {node}.
686 Reduction const reduction = ReduceJSCallConstruct(node); 689 Reduction const reduction = ReduceJSCallConstruct(node);
687 return reduction.Changed() ? reduction : Changed(node); 690 return reduction.Changed() ? reduction : Changed(node);
688 } 691 }
689 } 692 }
690 693
691 return NoChange(); 694 return NoChange();
692 } 695 }
693 696
697 Reduction JSCallReducer::ReduceJSCallConstructWithSpread(Node* node) {
698 DCHECK_EQ(IrOpcode::kJSCallConstructWithSpread, node->opcode());
699 CallConstructWithSpreadParameters const& p =
700 CallConstructWithSpreadParametersOf(node->op());
701 DCHECK_LE(3u, p.arity());
702 int arity = static_cast<int>(p.arity() - 2);
703
704 Node* spread = NodeProperties::GetValueInput(node, arity);
705
706 // Check if spread is an arguments object, and {node} is the only value user
707 // of spread (except for value uses in frame states).
708 if (spread->opcode() != IrOpcode::kJSCreateArguments) return NoChange();
709 for (Edge edge : spread->use_edges()) {
710 if (edge.from()->opcode() == IrOpcode::kStateValues) continue;
711 if (!NodeProperties::IsValueEdge(edge)) continue;
712 if (edge.from() == node) continue;
713 return NoChange();
714 }
715
716 // Get to the actual frame state from which to extract the arguments;
717 // we can only optimize this in case the {node} was already inlined into
718 // some other function (and same for the {spread}).
719 CreateArgumentsType type = CreateArgumentsTypeOf(spread->op());
720 Node* frame_state = NodeProperties::GetFrameStateInput(spread);
721 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
722 if (outer_state->opcode() != IrOpcode::kFrameState) return NoChange();
723 FrameStateInfo outer_info = OpParameter<FrameStateInfo>(outer_state);
724 if (outer_info.type() == FrameStateType::kArgumentsAdaptor) {
725 // Need to take the parameters from the arguments adaptor.
726 frame_state = outer_state;
727 }
728 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
729 int start_index = 0;
730 if (type == CreateArgumentsType::kMappedArguments) {
731 // Mapped arguments (sloppy mode) cannot be handled if they are aliased.
732 Handle<SharedFunctionInfo> shared;
733 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
734 if (shared->internal_formal_parameter_count() != 0) return NoChange();
735 } else if (type == CreateArgumentsType::kRestParameter) {
736 Handle<SharedFunctionInfo> shared;
737 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
738 start_index = shared->internal_formal_parameter_count();
739
740 // Only check the array iterator protector when we have a rest object.
741 if (!isolate()->IsArrayIteratorLookupChainIntact()) return NoChange();
742 // Add a code dependency on the string length overflow protector.
Benedikt Meurer 2017/01/30 09:14:16 Typo: string length overflow :-)
petermarshall 2017/01/30 09:43:57 Done
743 dependencies()->AssumePropertyCell(factory()->array_iterator_protector());
744 }
745
746 // Do checks to make sure we can actually avoid iteration.
747 if (!isolate()->initial_array_iterator_prototype_map()->is_stable()) {
Benedikt Meurer 2017/01/30 09:14:16 This should be done earlier, before you add depend
petermarshall 2017/01/30 09:43:58 Done
748 return NoChange();
749 }
750 dependencies()->AssumeMapStable(
751 isolate()->initial_array_iterator_prototype_map());
752
753 // Remove the spread input from the {node}.
754 node->RemoveInput(arity--);
755
756 // Add the actual parameters to the {node}, skipping the receiver.
757 Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
758 for (int i = start_index + 1; i < state_info.parameter_count(); ++i) {
759 node->InsertInput(graph()->zone(), static_cast<int>(++arity),
760 parameters->InputAt(i));
761 }
762
763 NodeProperties::ChangeOp(
764 node, javascript()->CallConstruct(arity + 2, 7, VectorSlotPair()));
765
766 return Changed(node);
767 }
768
694 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } 769 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); }
695 770
696 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } 771 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); }
697 772
773 Factory* JSCallReducer::factory() const { return isolate()->factory(); }
774
698 CommonOperatorBuilder* JSCallReducer::common() const { 775 CommonOperatorBuilder* JSCallReducer::common() const {
699 return jsgraph()->common(); 776 return jsgraph()->common();
700 } 777 }
701 778
702 JSOperatorBuilder* JSCallReducer::javascript() const { 779 JSOperatorBuilder* JSCallReducer::javascript() const {
703 return jsgraph()->javascript(); 780 return jsgraph()->javascript();
704 } 781 }
705 782
706 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { 783 SimplifiedOperatorBuilder* JSCallReducer::simplified() const {
707 return jsgraph()->simplified(); 784 return jsgraph()->simplified();
708 } 785 }
709 786
710 } // namespace compiler 787 } // namespace compiler
711 } // namespace internal 788 } // namespace internal
712 } // namespace v8 789 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-call-reducer.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698