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/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 node->ReplaceInput(3, frame_state); | 257 node->ReplaceInput(3, frame_state); |
258 node->ReplaceInput(4, effect); | 258 node->ReplaceInput(4, effect); |
259 node->ReplaceInput(5, control); | 259 node->ReplaceInput(5, control); |
260 node->TrimInputCount(6); | 260 node->TrimInputCount(6); |
261 NodeProperties::ChangeOp(node, javascript()->OrdinaryHasInstance()); | 261 NodeProperties::ChangeOp(node, javascript()->OrdinaryHasInstance()); |
262 return Changed(node); | 262 return Changed(node); |
263 } | 263 } |
264 | 264 |
265 namespace { | 265 namespace { |
266 | 266 |
267 // TODO(turbofan): Share with similar functionality in JSInliningHeuristic | |
268 // and JSNativeContextSpecialization, i.e. move to NodeProperties helper?! | |
269 MaybeHandle<Map> InferReceiverMap(Node* node) { | |
270 Node* receiver = NodeProperties::GetValueInput(node, 1); | |
271 Node* effect = NodeProperties::GetEffectInput(node); | |
272 // Check if the {node} is dominated by a CheckMaps with a single map | |
273 // for the {receiver}, and if so use that map for the lowering below. | |
274 for (Node* dominator = effect;;) { | |
275 if (dominator->opcode() == IrOpcode::kCheckMaps && | |
276 NodeProperties::IsSame(dominator->InputAt(0), receiver)) { | |
277 if (dominator->op()->ValueInputCount() == 2) { | |
278 HeapObjectMatcher m(dominator->InputAt(1)); | |
279 if (m.HasValue()) return Handle<Map>::cast(m.Value()); | |
280 } | |
281 return MaybeHandle<Map>(); | |
282 } | |
283 if (dominator->op()->EffectInputCount() != 1) { | |
284 // Didn't find any appropriate CheckMaps node. | |
285 return MaybeHandle<Map>(); | |
286 } | |
287 dominator = NodeProperties::GetEffectInput(dominator); | |
288 } | |
289 } | |
290 | |
291 bool CanInlineApiCall(Isolate* isolate, Node* node, | 267 bool CanInlineApiCall(Isolate* isolate, Node* node, |
292 Handle<FunctionTemplateInfo> function_template_info) { | 268 Handle<FunctionTemplateInfo> function_template_info) { |
293 DCHECK(node->opcode() == IrOpcode::kJSCall); | 269 DCHECK(node->opcode() == IrOpcode::kJSCall); |
294 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; | 270 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; |
295 if (function_template_info->call_code()->IsUndefined(isolate)) { | 271 if (function_template_info->call_code()->IsUndefined(isolate)) { |
296 return false; | 272 return false; |
297 } | 273 } |
298 CallParameters const& params = CallParametersOf(node->op()); | 274 CallParameters const& params = CallParametersOf(node->op()); |
299 // CallApiCallbackStub expects the target in a register, so we count it out, | 275 // CallApiCallbackStub expects the target in a register, so we count it out, |
300 // and counts the receiver as an implicit argument, so we count the receiver | 276 // and counts the receiver as an implicit argument, so we count the receiver |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 *holder = prototype; | 313 *holder = prototype; |
338 return kHolderFound; | 314 return kHolderFound; |
339 } | 315 } |
340 } | 316 } |
341 return kHolderNotFound; | 317 return kHolderNotFound; |
342 } | 318 } |
343 | 319 |
344 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ | 320 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ |
345 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { | 321 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { |
346 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | 322 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 323 Node* receiver = NodeProperties::GetValueInput(node, 1); |
| 324 Node* effect = NodeProperties::GetEffectInput(node); |
347 | 325 |
348 // Try to determine the {receiver} map. | 326 // Try to determine the {receiver} map. |
349 Handle<Map> receiver_map; | 327 ZoneHandleSet<Map> receiver_maps; |
350 if (InferReceiverMap(node).ToHandle(&receiver_map)) { | 328 if (NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps)) { |
351 // Check if we can constant-fold the {receiver} map. | 329 Handle<Object> receiver_prototype(receiver_maps[0]->prototype(), isolate()); |
352 if (!receiver_map->IsJSProxyMap() && | 330 |
353 !receiver_map->has_hidden_prototype() && | 331 // Check if we can constant-fold the {receiver_prototype}. |
354 !receiver_map->is_access_check_needed()) { | 332 for (size_t i = 0; i < receiver_maps.size(); ++i) { |
355 Handle<Object> receiver_prototype(receiver_map->prototype(), isolate()); | 333 Handle<Map> const receiver_map = receiver_maps[i]; |
356 Node* value = jsgraph()->Constant(receiver_prototype); | 334 if (receiver_map->IsJSProxyMap() || |
357 ReplaceWithValue(node, value); | 335 receiver_map->has_hidden_prototype() || |
358 return Replace(value); | 336 receiver_map->is_access_check_needed() || |
| 337 receiver_map->prototype() != *receiver_prototype) { |
| 338 return NoChange(); |
| 339 } |
359 } | 340 } |
| 341 Node* value = jsgraph()->Constant(receiver_prototype); |
| 342 ReplaceWithValue(node, value); |
| 343 return Replace(value); |
360 } | 344 } |
361 | 345 |
362 return NoChange(); | 346 return NoChange(); |
363 } | 347 } |
364 | 348 |
365 Reduction JSCallReducer::ReduceCallApiFunction( | 349 Reduction JSCallReducer::ReduceCallApiFunction( |
366 Node* node, Node* target, | 350 Node* node, Node* target, |
367 Handle<FunctionTemplateInfo> function_template_info) { | 351 Handle<FunctionTemplateInfo> function_template_info) { |
368 Isolate* isolate = this->isolate(); | 352 Isolate* isolate = this->isolate(); |
369 CHECK(!isolate->serializer_enabled()); | 353 CHECK(!isolate->serializer_enabled()); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 return jsgraph()->javascript(); | 792 return jsgraph()->javascript(); |
809 } | 793 } |
810 | 794 |
811 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 795 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
812 return jsgraph()->simplified(); | 796 return jsgraph()->simplified(); |
813 } | 797 } |
814 | 798 |
815 } // namespace compiler | 799 } // namespace compiler |
816 } // namespace internal | 800 } // namespace internal |
817 } // namespace v8 | 801 } // namespace v8 |
OLD | NEW |