| 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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 Handle<JSObject> prototype(JSObject::cast(object_map->prototype())); | 320 Handle<JSObject> prototype(JSObject::cast(object_map->prototype())); |
| 321 object_map = handle(prototype->map()); | 321 object_map = handle(prototype->map()); |
| 322 if (expected_receiver_type->IsTemplateFor(*object_map)) { | 322 if (expected_receiver_type->IsTemplateFor(*object_map)) { |
| 323 *holder = prototype; | 323 *holder = prototype; |
| 324 return kHolderFound; | 324 return kHolderFound; |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 return kHolderNotFound; | 327 return kHolderNotFound; |
| 328 } | 328 } |
| 329 | 329 |
| 330 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ | 330 Reduction JSCallReducer::ReduceObjectGetPrototype(Node* node, Node* object) { |
| 331 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { | |
| 332 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | |
| 333 Node* receiver = NodeProperties::GetValueInput(node, 1); | |
| 334 Node* effect = NodeProperties::GetEffectInput(node); | 331 Node* effect = NodeProperties::GetEffectInput(node); |
| 335 | 332 |
| 336 // Try to determine the {receiver} map. | 333 // Try to determine the {object} map. |
| 337 ZoneHandleSet<Map> receiver_maps; | 334 ZoneHandleSet<Map> object_maps; |
| 338 NodeProperties::InferReceiverMapsResult result = | 335 NodeProperties::InferReceiverMapsResult result = |
| 339 NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps); | 336 NodeProperties::InferReceiverMaps(object, effect, &object_maps); |
| 340 if (result != NodeProperties::kNoReceiverMaps) { | 337 if (result != NodeProperties::kNoReceiverMaps) { |
| 341 Handle<Map> candidate_map( | 338 Handle<Map> candidate_map( |
| 342 receiver_maps[0]->GetPrototypeChainRootMap(isolate())); | 339 object_maps[0]->GetPrototypeChainRootMap(isolate())); |
| 343 Handle<Object> candidate_prototype(candidate_map->prototype(), isolate()); | 340 Handle<Object> candidate_prototype(candidate_map->prototype(), isolate()); |
| 344 | 341 |
| 342 // We cannot deal with primitives here. |
| 343 if (candidate_map->IsPrimitiveMap()) return NoChange(); |
| 344 |
| 345 // Check if we can constant-fold the {candidate_prototype}. | 345 // Check if we can constant-fold the {candidate_prototype}. |
| 346 for (size_t i = 0; i < receiver_maps.size(); ++i) { | 346 for (size_t i = 0; i < object_maps.size(); ++i) { |
| 347 Handle<Map> const receiver_map( | 347 Handle<Map> const object_map( |
| 348 receiver_maps[i]->GetPrototypeChainRootMap(isolate())); | 348 object_maps[i]->GetPrototypeChainRootMap(isolate())); |
| 349 if (receiver_map->IsJSProxyMap() || | 349 if (object_map->IsSpecialReceiverMap() || |
| 350 receiver_map->has_hidden_prototype() || | 350 object_map->has_hidden_prototype() || |
| 351 receiver_map->is_access_check_needed() || | 351 object_map->prototype() != *candidate_prototype) { |
| 352 receiver_map->prototype() != *candidate_prototype) { | 352 // We exclude special receivers, like JSProxy or API objects that |
| 353 // might require access checks here; we also don't want to deal |
| 354 // with hidden prototypes at this point. |
| 353 return NoChange(); | 355 return NoChange(); |
| 354 } | 356 } |
| 355 if (result == NodeProperties::kUnreliableReceiverMaps && | 357 if (result == NodeProperties::kUnreliableReceiverMaps && |
| 356 !receiver_map->is_stable()) { | 358 !object_map->is_stable()) { |
| 357 return NoChange(); | 359 return NoChange(); |
| 358 } | 360 } |
| 359 } | 361 } |
| 360 if (result == NodeProperties::kUnreliableReceiverMaps) { | 362 if (result == NodeProperties::kUnreliableReceiverMaps) { |
| 361 for (size_t i = 0; i < receiver_maps.size(); ++i) { | 363 for (size_t i = 0; i < object_maps.size(); ++i) { |
| 362 dependencies()->AssumeMapStable(receiver_maps[i]); | 364 dependencies()->AssumeMapStable(object_maps[i]); |
| 363 } | 365 } |
| 364 } | 366 } |
| 365 Node* value = jsgraph()->Constant(candidate_prototype); | 367 Node* value = jsgraph()->Constant(candidate_prototype); |
| 366 ReplaceWithValue(node, value); | 368 ReplaceWithValue(node, value); |
| 367 return Replace(value); | 369 return Replace(value); |
| 368 } | 370 } |
| 369 | 371 |
| 370 return NoChange(); | 372 return NoChange(); |
| 371 } | 373 } |
| 372 | 374 |
| 375 // ES6 section 19.1.2.11 Object.getPrototypeOf ( O ) |
| 376 Reduction JSCallReducer::ReduceObjectGetPrototypeOf(Node* node) { |
| 377 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 378 Node* object = (node->op()->ValueInputCount() >= 3) |
| 379 ? NodeProperties::GetValueInput(node, 2) |
| 380 : jsgraph()->UndefinedConstant(); |
| 381 return ReduceObjectGetPrototype(node, object); |
| 382 } |
| 383 |
| 384 // ES6 section B.2.2.1.1 get Object.prototype.__proto__ |
| 385 Reduction JSCallReducer::ReduceObjectPrototypeGetProto(Node* node) { |
| 386 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 387 Node* receiver = NodeProperties::GetValueInput(node, 1); |
| 388 return ReduceObjectGetPrototype(node, receiver); |
| 389 } |
| 390 |
| 391 // ES6 section 26.1.7 Reflect.getPrototypeOf ( target ) |
| 392 Reduction JSCallReducer::ReduceReflectGetPrototypeOf(Node* node) { |
| 393 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 394 Node* target = (node->op()->ValueInputCount() >= 3) |
| 395 ? NodeProperties::GetValueInput(node, 2) |
| 396 : jsgraph()->UndefinedConstant(); |
| 397 return ReduceObjectGetPrototype(node, target); |
| 398 } |
| 399 |
| 373 Reduction JSCallReducer::ReduceCallApiFunction( | 400 Reduction JSCallReducer::ReduceCallApiFunction( |
| 374 Node* node, Node* target, | 401 Node* node, Node* target, |
| 375 Handle<FunctionTemplateInfo> function_template_info) { | 402 Handle<FunctionTemplateInfo> function_template_info) { |
| 376 Isolate* isolate = this->isolate(); | 403 Isolate* isolate = this->isolate(); |
| 377 CHECK(!isolate->serializer_enabled()); | 404 CHECK(!isolate->serializer_enabled()); |
| 378 HeapObjectMatcher m(target); | 405 HeapObjectMatcher m(target); |
| 379 DCHECK(m.HasValue() && m.Value()->IsJSFunction()); | 406 DCHECK(m.HasValue() && m.Value()->IsJSFunction()); |
| 380 if (!CanInlineApiCall(isolate, node, function_template_info)) { | 407 if (!CanInlineApiCall(isolate, node, function_template_info)) { |
| 381 return NoChange(); | 408 return NoChange(); |
| 382 } | 409 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 case Builtins::kBooleanConstructor: | 590 case Builtins::kBooleanConstructor: |
| 564 return ReduceBooleanConstructor(node); | 591 return ReduceBooleanConstructor(node); |
| 565 case Builtins::kFunctionPrototypeApply: | 592 case Builtins::kFunctionPrototypeApply: |
| 566 return ReduceFunctionPrototypeApply(node); | 593 return ReduceFunctionPrototypeApply(node); |
| 567 case Builtins::kFunctionPrototypeCall: | 594 case Builtins::kFunctionPrototypeCall: |
| 568 return ReduceFunctionPrototypeCall(node); | 595 return ReduceFunctionPrototypeCall(node); |
| 569 case Builtins::kFunctionPrototypeHasInstance: | 596 case Builtins::kFunctionPrototypeHasInstance: |
| 570 return ReduceFunctionPrototypeHasInstance(node); | 597 return ReduceFunctionPrototypeHasInstance(node); |
| 571 case Builtins::kNumberConstructor: | 598 case Builtins::kNumberConstructor: |
| 572 return ReduceNumberConstructor(node); | 599 return ReduceNumberConstructor(node); |
| 600 case Builtins::kObjectGetPrototypeOf: |
| 601 return ReduceObjectGetPrototypeOf(node); |
| 573 case Builtins::kObjectPrototypeGetProto: | 602 case Builtins::kObjectPrototypeGetProto: |
| 574 return ReduceObjectPrototypeGetProto(node); | 603 return ReduceObjectPrototypeGetProto(node); |
| 604 case Builtins::kReflectGetPrototypeOf: |
| 605 return ReduceReflectGetPrototypeOf(node); |
| 575 default: | 606 default: |
| 576 break; | 607 break; |
| 577 } | 608 } |
| 578 | 609 |
| 579 // Check for the Array constructor. | 610 // Check for the Array constructor. |
| 580 if (*function == function->native_context()->array_function()) { | 611 if (*function == function->native_context()->array_function()) { |
| 581 return ReduceArrayConstructor(node); | 612 return ReduceArrayConstructor(node); |
| 582 } | 613 } |
| 583 | 614 |
| 584 if (shared->IsApiFunction()) { | 615 if (shared->IsApiFunction()) { |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 return jsgraph()->javascript(); | 874 return jsgraph()->javascript(); |
| 844 } | 875 } |
| 845 | 876 |
| 846 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 877 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
| 847 return jsgraph()->simplified(); | 878 return jsgraph()->simplified(); |
| 848 } | 879 } |
| 849 | 880 |
| 850 } // namespace compiler | 881 } // namespace compiler |
| 851 } // namespace internal | 882 } // namespace internal |
| 852 } // namespace v8 | 883 } // namespace v8 |
| OLD | NEW |