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/compiler/js-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
6 | 6 |
7 #include "src/builtins/builtins-utils.h" | 7 #include "src/builtins/builtins-utils.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 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 // Unify representations between construct and call nodes. | 1535 // Unify representations between construct and call nodes. |
1536 // Remove new target and add receiver as a stack parameter. | 1536 // Remove new target and add receiver as a stack parameter. |
1537 Node* receiver = jsgraph->UndefinedConstant(); | 1537 Node* receiver = jsgraph->UndefinedConstant(); |
1538 node->RemoveInput(arity + 1); | 1538 node->RemoveInput(arity + 1); |
1539 node->InsertInput(zone, 1, receiver); | 1539 node->InsertInput(zone, 1, receiver); |
1540 } | 1540 } |
1541 | 1541 |
1542 const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver; | 1542 const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver; |
1543 Node* argc_node = jsgraph->Int32Constant(argc); | 1543 Node* argc_node = jsgraph->Int32Constant(argc); |
1544 | 1544 |
1545 node->InsertInput(zone, arity + 2, argc_node); | 1545 static const int kStubAndReceiver = 2; |
1546 node->InsertInput(zone, arity + 3, target); | 1546 int cursor = arity + kStubAndReceiver; |
1547 node->InsertInput(zone, arity + 4, new_target); | 1547 node->InsertInput(zone, cursor++, argc_node); |
| 1548 node->InsertInput(zone, cursor++, target); |
| 1549 node->InsertInput(zone, cursor++, new_target); |
1548 | 1550 |
1549 Address entry = Builtins::CppEntryOf(builtin_index); | 1551 Address entry = Builtins::CppEntryOf(builtin_index); |
1550 ExternalReference entry_ref(ExternalReference(entry, isolate)); | 1552 ExternalReference entry_ref(ExternalReference(entry, isolate)); |
1551 Node* entry_node = jsgraph->ExternalConstant(entry_ref); | 1553 Node* entry_node = jsgraph->ExternalConstant(entry_ref); |
1552 | 1554 |
1553 node->InsertInput(zone, arity + 5, entry_node); | 1555 node->InsertInput(zone, cursor++, entry_node); |
1554 node->InsertInput(zone, arity + 6, argc_node); | 1556 node->InsertInput(zone, cursor++, argc_node); |
1555 | 1557 |
1556 static const int kReturnCount = 1; | 1558 static const int kReturnCount = 1; |
1557 const char* debug_name = Builtins::name(builtin_index); | 1559 const char* debug_name = Builtins::name(builtin_index); |
1558 Operator::Properties properties = node->op()->properties(); | 1560 Operator::Properties properties = node->op()->properties(); |
1559 CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor( | 1561 CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor( |
1560 zone, kReturnCount, argc, debug_name, properties, flags); | 1562 zone, kReturnCount, argc, debug_name, properties, flags); |
1561 | 1563 |
1562 NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc)); | 1564 NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc)); |
1563 } | 1565 } |
1564 | 1566 |
| 1567 bool NeedsArgumentAdaptorFrame(Handle<SharedFunctionInfo> shared, int arity) { |
| 1568 static const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 1569 const int num_decl_parms = shared->internal_formal_parameter_count(); |
| 1570 return (num_decl_parms != arity && num_decl_parms != sentinel); |
| 1571 } |
| 1572 |
1565 } // namespace | 1573 } // namespace |
1566 | 1574 |
1567 Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) { | 1575 Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) { |
1568 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); | 1576 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); |
1569 CallConstructParameters const& p = CallConstructParametersOf(node->op()); | 1577 CallConstructParameters const& p = CallConstructParametersOf(node->op()); |
1570 DCHECK_LE(2u, p.arity()); | 1578 DCHECK_LE(2u, p.arity()); |
1571 int const arity = static_cast<int>(p.arity() - 2); | 1579 int const arity = static_cast<int>(p.arity() - 2); |
1572 Node* target = NodeProperties::GetValueInput(node, 0); | 1580 Node* target = NodeProperties::GetValueInput(node, 0); |
1573 Type* target_type = NodeProperties::GetType(target); | 1581 Type* target_type = NodeProperties::GetType(target); |
1574 Node* new_target = NodeProperties::GetValueInput(node, arity + 1); | 1582 Node* new_target = NodeProperties::GetValueInput(node, arity + 1); |
1575 Node* effect = NodeProperties::GetEffectInput(node); | 1583 Node* effect = NodeProperties::GetEffectInput(node); |
1576 Node* control = NodeProperties::GetControlInput(node); | 1584 Node* control = NodeProperties::GetControlInput(node); |
1577 | 1585 |
1578 // Check if {target} is a known JSFunction. | 1586 // Check if {target} is a known JSFunction. |
1579 if (target_type->IsConstant() && | 1587 if (target_type->IsConstant() && |
1580 target_type->AsConstant()->Value()->IsJSFunction()) { | 1588 target_type->AsConstant()->Value()->IsJSFunction()) { |
1581 Handle<JSFunction> function = | 1589 Handle<JSFunction> function = |
1582 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); | 1590 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); |
1583 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); | 1591 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); |
1584 const int builtin_index = shared->construct_stub()->builtin_index(); | 1592 const int builtin_index = shared->construct_stub()->builtin_index(); |
1585 const bool is_builtin = (builtin_index != -1); | 1593 const bool is_builtin = (builtin_index != -1); |
1586 | 1594 |
1587 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 1595 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
1588 | 1596 |
1589 if (is_builtin && Builtins::HasCppImplementation(builtin_index) && | 1597 if (is_builtin && Builtins::HasCppImplementation(builtin_index) && |
1590 (shared->internal_formal_parameter_count() == arity || | 1598 !NeedsArgumentAdaptorFrame(shared, arity)) { |
1591 shared->internal_formal_parameter_count() == | |
1592 SharedFunctionInfo::kDontAdaptArgumentsSentinel)) { | |
1593 // Patch {node} to a direct CEntryStub call. | 1599 // Patch {node} to a direct CEntryStub call. |
1594 | 1600 |
1595 // Load the context from the {target}. | 1601 // Load the context from the {target}. |
1596 Node* context = effect = graph()->NewNode( | 1602 Node* context = effect = graph()->NewNode( |
1597 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), | 1603 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), |
1598 target, effect, control); | 1604 target, effect, control); |
1599 NodeProperties::ReplaceContextInput(node, context); | 1605 NodeProperties::ReplaceContextInput(node, context); |
1600 | 1606 |
1601 // Update the effect dependency for the {node}. | 1607 // Update the effect dependency for the {node}. |
1602 NodeProperties::ReplaceEffectInput(node, effect); | 1608 NodeProperties::ReplaceEffectInput(node, effect); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 NodeProperties::ReplaceEffectInput(node, effect); | 1700 NodeProperties::ReplaceEffectInput(node, effect); |
1695 | 1701 |
1696 // Compute flags for the call. | 1702 // Compute flags for the call. |
1697 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 1703 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
1698 if (p.tail_call_mode() == TailCallMode::kAllow) { | 1704 if (p.tail_call_mode() == TailCallMode::kAllow) { |
1699 flags |= CallDescriptor::kSupportsTailCalls; | 1705 flags |= CallDescriptor::kSupportsTailCalls; |
1700 } | 1706 } |
1701 | 1707 |
1702 Node* new_target = jsgraph()->UndefinedConstant(); | 1708 Node* new_target = jsgraph()->UndefinedConstant(); |
1703 Node* argument_count = jsgraph()->Int32Constant(arity); | 1709 Node* argument_count = jsgraph()->Int32Constant(arity); |
1704 if (is_builtin && Builtins::HasCppImplementation(builtin_index) && | 1710 if (NeedsArgumentAdaptorFrame(shared, arity)) { |
1705 (shared->internal_formal_parameter_count() == arity || | |
1706 shared->internal_formal_parameter_count() == | |
1707 SharedFunctionInfo::kDontAdaptArgumentsSentinel)) { | |
1708 // Patch {node} to a direct CEntryStub call. | |
1709 ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); | |
1710 } else if (shared->internal_formal_parameter_count() == arity || | |
1711 shared->internal_formal_parameter_count() == | |
1712 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | |
1713 // Patch {node} to a direct call. | |
1714 node->InsertInput(graph()->zone(), arity + 2, new_target); | |
1715 node->InsertInput(graph()->zone(), arity + 3, argument_count); | |
1716 NodeProperties::ChangeOp(node, | |
1717 common()->Call(Linkage::GetJSCallDescriptor( | |
1718 graph()->zone(), false, 1 + arity, flags))); | |
1719 } else { | |
1720 // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline. | 1711 // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline. |
1721 Callable callable = CodeFactory::ArgumentAdaptor(isolate()); | 1712 Callable callable = CodeFactory::ArgumentAdaptor(isolate()); |
1722 node->InsertInput(graph()->zone(), 0, | 1713 node->InsertInput(graph()->zone(), 0, |
1723 jsgraph()->HeapConstant(callable.code())); | 1714 jsgraph()->HeapConstant(callable.code())); |
1724 node->InsertInput(graph()->zone(), 2, new_target); | 1715 node->InsertInput(graph()->zone(), 2, new_target); |
1725 node->InsertInput(graph()->zone(), 3, argument_count); | 1716 node->InsertInput(graph()->zone(), 3, argument_count); |
1726 node->InsertInput( | 1717 node->InsertInput( |
1727 graph()->zone(), 4, | 1718 graph()->zone(), 4, |
1728 jsgraph()->Int32Constant(shared->internal_formal_parameter_count())); | 1719 jsgraph()->Int32Constant(shared->internal_formal_parameter_count())); |
1729 NodeProperties::ChangeOp( | 1720 NodeProperties::ChangeOp( |
1730 node, common()->Call(Linkage::GetStubCallDescriptor( | 1721 node, common()->Call(Linkage::GetStubCallDescriptor( |
1731 isolate(), graph()->zone(), callable.descriptor(), | 1722 isolate(), graph()->zone(), callable.descriptor(), |
1732 1 + arity, flags))); | 1723 1 + arity, flags))); |
| 1724 } else if (is_builtin && Builtins::HasCppImplementation(builtin_index)) { |
| 1725 // Patch {node} to a direct CEntryStub call. |
| 1726 ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); |
| 1727 } else { |
| 1728 // Patch {node} to a direct call. |
| 1729 node->InsertInput(graph()->zone(), arity + 2, new_target); |
| 1730 node->InsertInput(graph()->zone(), arity + 3, argument_count); |
| 1731 NodeProperties::ChangeOp(node, |
| 1732 common()->Call(Linkage::GetJSCallDescriptor( |
| 1733 graph()->zone(), false, 1 + arity, flags))); |
1733 } | 1734 } |
1734 return Changed(node); | 1735 return Changed(node); |
1735 } | 1736 } |
1736 | 1737 |
1737 // Check if {target} is a JSFunction. | 1738 // Check if {target} is a JSFunction. |
1738 if (target_type->Is(Type::Function())) { | 1739 if (target_type->Is(Type::Function())) { |
1739 // Compute flags for the call. | 1740 // Compute flags for the call. |
1740 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 1741 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
1741 if (p.tail_call_mode() == TailCallMode::kAllow) { | 1742 if (p.tail_call_mode() == TailCallMode::kAllow) { |
1742 flags |= CallDescriptor::kSupportsTailCalls; | 1743 flags |= CallDescriptor::kSupportsTailCalls; |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2213 } | 2214 } |
2214 | 2215 |
2215 | 2216 |
2216 CompilationDependencies* JSTypedLowering::dependencies() const { | 2217 CompilationDependencies* JSTypedLowering::dependencies() const { |
2217 return dependencies_; | 2218 return dependencies_; |
2218 } | 2219 } |
2219 | 2220 |
2220 } // namespace compiler | 2221 } // namespace compiler |
2221 } // namespace internal | 2222 } // namespace internal |
2222 } // namespace v8 | 2223 } // namespace v8 |
OLD | NEW |