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

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

Issue 2659623002: [turbofan] Reduce CallConstructWithSpread where iteration is not observable. (Closed)
Patch Set: respond to comments from Benedikt 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 // Do check to make sure we can actually avoid iteration.
705 if (!isolate()->initial_array_iterator_prototype_map()->is_stable()) {
706 return NoChange();
707 }
708
709 Node* spread = NodeProperties::GetValueInput(node, arity);
710
711 // Check if spread is an arguments object, and {node} is the only value user
712 // of spread (except for value uses in frame states).
713 if (spread->opcode() != IrOpcode::kJSCreateArguments) return NoChange();
714 for (Edge edge : spread->use_edges()) {
715 if (edge.from()->opcode() == IrOpcode::kStateValues) continue;
716 if (!NodeProperties::IsValueEdge(edge)) continue;
717 if (edge.from() == node) continue;
718 return NoChange();
719 }
720
721 // Get to the actual frame state from which to extract the arguments;
722 // we can only optimize this in case the {node} was already inlined into
723 // some other function (and same for the {spread}).
724 CreateArgumentsType type = CreateArgumentsTypeOf(spread->op());
725 Node* frame_state = NodeProperties::GetFrameStateInput(spread);
726 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
727 if (outer_state->opcode() != IrOpcode::kFrameState) return NoChange();
728 FrameStateInfo outer_info = OpParameter<FrameStateInfo>(outer_state);
729 if (outer_info.type() == FrameStateType::kArgumentsAdaptor) {
730 // Need to take the parameters from the arguments adaptor.
731 frame_state = outer_state;
732 }
733 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
734 int start_index = 0;
735 if (type == CreateArgumentsType::kMappedArguments) {
736 // Mapped arguments (sloppy mode) cannot be handled if they are aliased.
737 Handle<SharedFunctionInfo> shared;
738 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
739 if (shared->internal_formal_parameter_count() != 0) return NoChange();
740 } else if (type == CreateArgumentsType::kRestParameter) {
741 Handle<SharedFunctionInfo> shared;
742 if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
743 start_index = shared->internal_formal_parameter_count();
744
745 // Only check the array iterator protector when we have a rest object.
746 if (!isolate()->IsArrayIteratorLookupChainIntact()) return NoChange();
747 // Add a code dependency on the array iterator protector.
748 dependencies()->AssumePropertyCell(factory()->array_iterator_protector());
749 }
750
751 dependencies()->AssumeMapStable(
752 isolate()->initial_array_iterator_prototype_map());
753
754 // Remove the spread input from the {node}.
755 node->RemoveInput(arity--);
756
757 // Add the actual parameters to the {node}, skipping the receiver.
758 Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
759 for (int i = start_index + 1; i < state_info.parameter_count(); ++i) {
760 node->InsertInput(graph()->zone(), static_cast<int>(++arity),
761 parameters->InputAt(i));
762 }
763
764 NodeProperties::ChangeOp(
765 node, javascript()->CallConstruct(arity + 2, 7, VectorSlotPair()));
766
767 return Changed(node);
768 }
769
694 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } 770 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); }
695 771
696 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } 772 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); }
697 773
774 Factory* JSCallReducer::factory() const { return isolate()->factory(); }
775
698 CommonOperatorBuilder* JSCallReducer::common() const { 776 CommonOperatorBuilder* JSCallReducer::common() const {
699 return jsgraph()->common(); 777 return jsgraph()->common();
700 } 778 }
701 779
702 JSOperatorBuilder* JSCallReducer::javascript() const { 780 JSOperatorBuilder* JSCallReducer::javascript() const {
703 return jsgraph()->javascript(); 781 return jsgraph()->javascript();
704 } 782 }
705 783
706 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { 784 SimplifiedOperatorBuilder* JSCallReducer::simplified() const {
707 return jsgraph()->simplified(); 785 return jsgraph()->simplified();
708 } 786 }
709 787
710 } // namespace compiler 788 } // namespace compiler
711 } // namespace internal 789 } // namespace internal
712 } // namespace v8 790 } // 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