Chromium Code Reviews| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 (is_builtin && Builtins::HasCppImplementation(builtin_index) && |
| 1705 (shared->internal_formal_parameter_count() == arity || | 1711 !NeedsArgumentAdaptorFrame(shared, arity)) { |
| 1706 shared->internal_formal_parameter_count() == | |
| 1707 SharedFunctionInfo::kDontAdaptArgumentsSentinel)) { | |
| 1708 // Patch {node} to a direct CEntryStub call. | 1712 // Patch {node} to a direct CEntryStub call. |
| 1709 ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); | 1713 ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); |
| 1710 } else if (shared->internal_formal_parameter_count() == arity || | 1714 } else if (!NeedsArgumentAdaptorFrame(shared, arity)) { |
| 1711 shared->internal_formal_parameter_count() == | |
| 1712 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | |
| 1713 // Patch {node} to a direct call. | 1715 // Patch {node} to a direct call. |
| 1714 node->InsertInput(graph()->zone(), arity + 2, new_target); | 1716 node->InsertInput(graph()->zone(), arity + 2, new_target); |
| 1715 node->InsertInput(graph()->zone(), arity + 3, argument_count); | 1717 node->InsertInput(graph()->zone(), arity + 3, argument_count); |
| 1716 NodeProperties::ChangeOp(node, | 1718 NodeProperties::ChangeOp(node, |
| 1717 common()->Call(Linkage::GetJSCallDescriptor( | 1719 common()->Call(Linkage::GetJSCallDescriptor( |
| 1718 graph()->zone(), false, 1 + arity, flags))); | 1720 graph()->zone(), false, 1 + arity, flags))); |
| 1719 } else { | 1721 } else { |
| 1720 // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline. | 1722 // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline. |
| 1721 Callable callable = CodeFactory::ArgumentAdaptor(isolate()); | 1723 Callable callable = CodeFactory::ArgumentAdaptor(isolate()); |
| 1722 node->InsertInput(graph()->zone(), 0, | 1724 node->InsertInput(graph()->zone(), 0, |
| 1723 jsgraph()->HeapConstant(callable.code())); | 1725 jsgraph()->HeapConstant(callable.code())); |
| 1724 node->InsertInput(graph()->zone(), 2, new_target); | 1726 node->InsertInput(graph()->zone(), 2, new_target); |
| 1725 node->InsertInput(graph()->zone(), 3, argument_count); | 1727 node->InsertInput(graph()->zone(), 3, argument_count); |
| 1726 node->InsertInput( | 1728 node->InsertInput( |
| 1727 graph()->zone(), 4, | 1729 graph()->zone(), 4, |
| 1728 jsgraph()->Int32Constant(shared->internal_formal_parameter_count())); | 1730 jsgraph()->Int32Constant(shared->internal_formal_parameter_count())); |
| 1729 NodeProperties::ChangeOp( | 1731 NodeProperties::ChangeOp( |
| 1730 node, common()->Call(Linkage::GetStubCallDescriptor( | 1732 node, common()->Call(Linkage::GetStubCallDescriptor( |
| 1731 isolate(), graph()->zone(), callable.descriptor(), | 1733 isolate(), graph()->zone(), callable.descriptor(), |
| 1732 1 + arity, flags))); | 1734 1 + arity, flags))); |
| 1733 } | 1735 } |
|
Jarin
2016/08/25 08:47:09
I am wondering whether it would be better to write
jgruber
2016/08/25 08:50:45
Good point! Done.
| |
| 1734 return Changed(node); | 1736 return Changed(node); |
| 1735 } | 1737 } |
| 1736 | 1738 |
| 1737 // Check if {target} is a JSFunction. | 1739 // Check if {target} is a JSFunction. |
| 1738 if (target_type->Is(Type::Function())) { | 1740 if (target_type->Is(Type::Function())) { |
| 1739 // Compute flags for the call. | 1741 // Compute flags for the call. |
| 1740 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 1742 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
| 1741 if (p.tail_call_mode() == TailCallMode::kAllow) { | 1743 if (p.tail_call_mode() == TailCallMode::kAllow) { |
| 1742 flags |= CallDescriptor::kSupportsTailCalls; | 1744 flags |= CallDescriptor::kSupportsTailCalls; |
| 1743 } | 1745 } |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2213 } | 2215 } |
| 2214 | 2216 |
| 2215 | 2217 |
| 2216 CompilationDependencies* JSTypedLowering::dependencies() const { | 2218 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2217 return dependencies_; | 2219 return dependencies_; |
| 2218 } | 2220 } |
| 2219 | 2221 |
| 2220 } // namespace compiler | 2222 } // namespace compiler |
| 2221 } // namespace internal | 2223 } // namespace internal |
| 2222 } // namespace v8 | 2224 } // namespace v8 |
| OLD | NEW |