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

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 2537763002: [turbofan] Also optimize instanceof with bound functions. (Closed)
Patch Set: Created 4 years 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
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-native-context-specialization.h" 5 #include "src/compiler/js-native-context-specialization.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 flags_(flags), 64 flags_(flags),
65 native_context_(native_context), 65 native_context_(native_context),
66 dependencies_(dependencies), 66 dependencies_(dependencies),
67 zone_(zone), 67 zone_(zone),
68 type_cache_(TypeCache::Get()) {} 68 type_cache_(TypeCache::Get()) {}
69 69
70 Reduction JSNativeContextSpecialization::Reduce(Node* node) { 70 Reduction JSNativeContextSpecialization::Reduce(Node* node) {
71 switch (node->opcode()) { 71 switch (node->opcode()) {
72 case IrOpcode::kJSInstanceOf: 72 case IrOpcode::kJSInstanceOf:
73 return ReduceJSInstanceOf(node); 73 return ReduceJSInstanceOf(node);
74 case IrOpcode::kJSOrdinaryHasInstance:
75 return ReduceJSOrdinaryHasInstance(node);
74 case IrOpcode::kJSLoadContext: 76 case IrOpcode::kJSLoadContext:
75 return ReduceJSLoadContext(node); 77 return ReduceJSLoadContext(node);
76 case IrOpcode::kJSLoadNamed: 78 case IrOpcode::kJSLoadNamed:
77 return ReduceJSLoadNamed(node); 79 return ReduceJSLoadNamed(node);
78 case IrOpcode::kJSStoreNamed: 80 case IrOpcode::kJSStoreNamed:
79 return ReduceJSStoreNamed(node); 81 return ReduceJSStoreNamed(node);
80 case IrOpcode::kJSLoadProperty: 82 case IrOpcode::kJSLoadProperty:
81 return ReduceJSLoadProperty(node); 83 return ReduceJSLoadProperty(node);
82 case IrOpcode::kJSStoreProperty: 84 case IrOpcode::kJSStoreProperty:
83 return ReduceJSStoreProperty(node); 85 return ReduceJSStoreProperty(node);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 128
127 // Monomorphic property access. 129 // Monomorphic property access.
128 effect = 130 effect =
129 BuildCheckMaps(constructor, effect, control, MapList{receiver_map}); 131 BuildCheckMaps(constructor, effect, control, MapList{receiver_map});
130 132
131 // Lower to OrdinaryHasInstance(C, O). 133 // Lower to OrdinaryHasInstance(C, O).
132 NodeProperties::ReplaceValueInput(node, constructor, 0); 134 NodeProperties::ReplaceValueInput(node, constructor, 0);
133 NodeProperties::ReplaceValueInput(node, object, 1); 135 NodeProperties::ReplaceValueInput(node, object, 1);
134 NodeProperties::ReplaceEffectInput(node, effect); 136 NodeProperties::ReplaceEffectInput(node, effect);
135 NodeProperties::ChangeOp(node, javascript()->OrdinaryHasInstance()); 137 NodeProperties::ChangeOp(node, javascript()->OrdinaryHasInstance());
136 return Changed(node); 138 Reduction const reduction = ReduceJSOrdinaryHasInstance(node);
139 return reduction.Changed() ? reduction : Changed(node);
137 } 140 }
138 } else if (access_info.IsDataConstant()) { 141 } else if (access_info.IsDataConstant()) {
139 DCHECK(access_info.constant()->IsCallable()); 142 DCHECK(access_info.constant()->IsCallable());
140 143
141 // Determine actual holder and perform prototype chain checks. 144 // Determine actual holder and perform prototype chain checks.
142 Handle<JSObject> holder; 145 Handle<JSObject> holder;
143 if (access_info.holder().ToHandle(&holder)) { 146 if (access_info.holder().ToHandle(&holder)) {
144 AssumePrototypesStable(access_info.receiver_maps(), holder); 147 AssumePrototypesStable(access_info.receiver_maps(), holder);
145 } 148 }
146 149
(...skipping 20 matching lines...) Expand all
167 edge.UpdateTo(value); 170 edge.UpdateTo(value);
168 Revisit(edge.from()); 171 Revisit(edge.from());
169 } 172 }
170 } 173 }
171 return Changed(node); 174 return Changed(node);
172 } 175 }
173 176
174 return NoChange(); 177 return NoChange();
175 } 178 }
176 179
180 Reduction JSNativeContextSpecialization::ReduceJSOrdinaryHasInstance(
181 Node* node) {
182 DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode());
183 Node* constructor = NodeProperties::GetValueInput(node, 0);
184 Node* object = NodeProperties::GetValueInput(node, 1);
185
186 // Check if the {constructor} is a JSBoundFunction.
187 HeapObjectMatcher m(constructor);
188 if (m.HasValue() && m.Value()->IsJSBoundFunction()) {
189 // OrdinaryHasInstance on bound functions turns into a recursive
190 // invocation of the instanceof operator again.
191 // ES6 section 7.3.19 OrdinaryHasInstance (C, O) step 2.
192 Handle<JSBoundFunction> function = Handle<JSBoundFunction>::cast(m.Value());
193 Handle<JSReceiver> bound_target_function(function->bound_target_function());
194 NodeProperties::ReplaceValueInput(node, object, 0);
195 NodeProperties::ReplaceValueInput(
196 node, jsgraph()->HeapConstant(bound_target_function), 1);
197 NodeProperties::ChangeOp(node, javascript()->InstanceOf());
198 Reduction const reduction = ReduceJSInstanceOf(node);
199 return reduction.Changed() ? reduction : Changed(node);
200 }
201
202 return NoChange();
203 }
204
177 Reduction JSNativeContextSpecialization::ReduceJSLoadContext(Node* node) { 205 Reduction JSNativeContextSpecialization::ReduceJSLoadContext(Node* node) {
178 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); 206 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
179 ContextAccess const& access = ContextAccessOf(node->op()); 207 ContextAccess const& access = ContextAccessOf(node->op());
180 // Specialize JSLoadContext(NATIVE_CONTEXT_INDEX) to the known native 208 // Specialize JSLoadContext(NATIVE_CONTEXT_INDEX) to the known native
181 // context (if any), so we can constant-fold those fields, which is 209 // context (if any), so we can constant-fold those fields, which is
182 // safe, since the NATIVE_CONTEXT_INDEX slot is always immutable. 210 // safe, since the NATIVE_CONTEXT_INDEX slot is always immutable.
183 if (access.index() == Context::NATIVE_CONTEXT_INDEX) { 211 if (access.index() == Context::NATIVE_CONTEXT_INDEX) {
184 Node* value = jsgraph()->HeapConstant(native_context()); 212 Node* value = jsgraph()->HeapConstant(native_context());
185 ReplaceWithValue(node, value); 213 ReplaceWithValue(node, value);
186 return Replace(value); 214 return Replace(value);
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 return jsgraph()->javascript(); 1832 return jsgraph()->javascript();
1805 } 1833 }
1806 1834
1807 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1835 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1808 return jsgraph()->simplified(); 1836 return jsgraph()->simplified();
1809 } 1837 }
1810 1838
1811 } // namespace compiler 1839 } // namespace compiler
1812 } // namespace internal 1840 } // namespace internal
1813 } // namespace v8 1841 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | test/mjsunit/compiler/instanceof-opt3.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698