| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/js-generic-lowering.h" | 8 #include "src/compiler/js-generic-lowering.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); | 507 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); |
| 508 Node* construct = NodeProperties::GetValueInput(node, 0); | 508 Node* construct = NodeProperties::GetValueInput(node, 0); |
| 509 node->InsertInput(zone(), 0, stub_code); | 509 node->InsertInput(zone(), 0, stub_code); |
| 510 node->InsertInput(zone(), 1, jsgraph()->Int32Constant(arity - 1)); | 510 node->InsertInput(zone(), 1, jsgraph()->Int32Constant(arity - 1)); |
| 511 node->InsertInput(zone(), 2, construct); | 511 node->InsertInput(zone(), 2, construct); |
| 512 node->InsertInput(zone(), 3, jsgraph()->UndefinedConstant()); | 512 node->InsertInput(zone(), 3, jsgraph()->UndefinedConstant()); |
| 513 node->set_op(common()->Call(desc)); | 513 node->set_op(common()->Call(desc)); |
| 514 } | 514 } |
| 515 | 515 |
| 516 | 516 |
| 517 bool JSGenericLowering::TryLowerDirectJSCall(Node* node) { | |
| 518 // Lower to a direct call to a constant JSFunction if legal. | |
| 519 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); | |
| 520 int arg_count = static_cast<int>(p.arity() - 2); | |
| 521 | |
| 522 // Check the function is a constant and is really a JSFunction. | |
| 523 HeapObjectMatcher<Object> function_const(node->InputAt(0)); | |
| 524 if (!function_const.HasValue()) return false; // not a constant. | |
| 525 Handle<Object> func = function_const.Value().handle(); | |
| 526 if (!func->IsJSFunction()) return false; // not a function. | |
| 527 Handle<JSFunction> function = Handle<JSFunction>::cast(func); | |
| 528 if (arg_count != function->shared()->internal_formal_parameter_count()) { | |
| 529 return false; | |
| 530 } | |
| 531 | |
| 532 // Check the receiver doesn't need to be wrapped. | |
| 533 Node* receiver = node->InputAt(1); | |
| 534 if (!NodeProperties::IsTyped(receiver)) return false; | |
| 535 Type* ok_receiver = Type::Union(Type::Undefined(), Type::Receiver(), zone()); | |
| 536 if (!NodeProperties::GetBounds(receiver).upper->Is(ok_receiver)) return false; | |
| 537 | |
| 538 // Update to the function context. | |
| 539 NodeProperties::ReplaceContextInput( | |
| 540 node, jsgraph()->HeapConstant(Handle<Context>(function->context()))); | |
| 541 CallDescriptor::Flags flags = FlagsForNode(node); | |
| 542 if (is_strict(p.language_mode())) flags |= CallDescriptor::kSupportsTailCalls; | |
| 543 CallDescriptor* desc = | |
| 544 Linkage::GetJSCallDescriptor(zone(), false, 1 + arg_count, flags); | |
| 545 node->set_op(common()->Call(desc)); | |
| 546 return true; | |
| 547 } | |
| 548 | |
| 549 | |
| 550 void JSGenericLowering::LowerJSCallFunction(Node* node) { | 517 void JSGenericLowering::LowerJSCallFunction(Node* node) { |
| 551 // Fast case: call function directly. | |
| 552 if (TryLowerDirectJSCall(node)) return; | |
| 553 | |
| 554 // General case: CallFunctionStub. | |
| 555 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); | 518 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
| 556 int arg_count = static_cast<int>(p.arity() - 2); | 519 int arg_count = static_cast<int>(p.arity() - 2); |
| 557 CallFunctionStub stub(isolate(), arg_count, p.flags()); | 520 CallFunctionStub stub(isolate(), arg_count, p.flags()); |
| 558 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); | 521 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); |
| 559 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 522 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); |
| 560 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 523 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 561 isolate(), zone(), d, static_cast<int>(p.arity() - 1), flags); | 524 isolate(), zone(), d, static_cast<int>(p.arity() - 1), flags); |
| 562 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); | 525 Node* stub_code = jsgraph()->HeapConstant(stub.GetCode()); |
| 563 node->InsertInput(zone(), 0, stub_code); | 526 node->InsertInput(zone(), 0, stub_code); |
| 564 node->set_op(common()->Call(desc)); | 527 node->set_op(common()->Call(desc)); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 } | 797 } |
| 835 | 798 |
| 836 | 799 |
| 837 MachineOperatorBuilder* JSGenericLowering::machine() const { | 800 MachineOperatorBuilder* JSGenericLowering::machine() const { |
| 838 return jsgraph()->machine(); | 801 return jsgraph()->machine(); |
| 839 } | 802 } |
| 840 | 803 |
| 841 } // namespace compiler | 804 } // namespace compiler |
| 842 } // namespace internal | 805 } // namespace internal |
| 843 } // namespace v8 | 806 } // namespace v8 |
| OLD | NEW |