Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 2261163002: Adapt arguments when inlining C++ builtins (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@inline-cpp-construct
Patch Set: Rebase Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 node->ReplaceInput(2, rglobal); 1498 node->ReplaceInput(2, rglobal);
1499 node->ReplaceInput(3, control); 1499 node->ReplaceInput(3, control);
1500 node->TrimInputCount(4); 1500 node->TrimInputCount(4);
1501 NodeProperties::ChangeOp(node, 1501 NodeProperties::ChangeOp(node,
1502 common()->Phi(MachineRepresentation::kTagged, 3)); 1502 common()->Phi(MachineRepresentation::kTagged, 3));
1503 return Changed(node); 1503 return Changed(node);
1504 } 1504 }
1505 1505
1506 namespace { 1506 namespace {
1507 1507
1508 static const int kStubAndReceiver = 2;
1509
1510 // Adapts arguments if required and returns the number of JS arguments. This
1511 // is always the number of formal arguments if we're adapting, and the current
1512 // arity otherwise.
1513 int MaybeAdaptArguments(Isolate* isolate, JSGraph* jsgraph, Node* node,
1514 int arity, SharedFunctionInfo* shared) {
1515 const int formal_parameter_count = shared->internal_formal_parameter_count();
1516 const bool should_adapt_arguments =
1517 formal_parameter_count != SharedFunctionInfo::kDontAdaptArgumentsSentinel;
1518
1519 if (!should_adapt_arguments) return arity;
1520
1521 if (arity < formal_parameter_count) {
1522 // Fewer actual than formal parameters, push the rest as undefined.
1523 Node* undefined = jsgraph->UndefinedConstant();
1524 for (int i = arity; i < formal_parameter_count; i++) {
1525 node->InsertInput(jsgraph->zone(), arity + kStubAndReceiver, undefined);
1526 }
1527 } else if (arity > formal_parameter_count) {
1528 // More actual than formal parameters, remove trailing parameters.
1529 for (int i = formal_parameter_count; i < arity; i++) {
1530 node->RemoveInput(formal_parameter_count + kStubAndReceiver);
1531 }
1532 }
1533
1534 return formal_parameter_count;
1535 }
1536
1508 void ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node, 1537 void ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node,
1509 int builtin_index, int arity, CallDescriptor::Flags flags) { 1538 int builtin_index, int arity, CallDescriptor::Flags flags) {
1510 // Patch {node} to a direct CEntryStub call. 1539 // Patch {node} to a direct CEntryStub call.
1511 // 1540 //
1512 // ----------- A r g u m e n t s ----------- 1541 // ----------- A r g u m e n t s -----------
1513 // -- 0: CEntryStub 1542 // -- 0: CEntryStub
1514 // --- Stack args --- 1543 // --- Stack args ---
1515 // -- 1: receiver 1544 // -- 1: receiver
1516 // -- [2, 2 + n[: the n actual arguments passed to the builtin 1545 // -- [2, 2 + n[: the n actual arguments passed to the builtin
1517 // -- 2 + n: argc, including the receiver and implicit args (Smi) 1546 // -- 2 + n: argc, including the receiver and implicit args (Smi)
1518 // -- 2 + n + 1: target 1547 // -- 2 + n + 1: target
1519 // -- 2 + n + 2: new_target 1548 // -- 2 + n + 2: new_target
1520 // --- Register args --- 1549 // --- Register args ---
1521 // -- 2 + n + 3: the C entry point 1550 // -- 2 + n + 3: the C entry point
1522 // -- 2 + n + 4: argc (Int32) 1551 // -- 2 + n + 4: argc (Int32)
1523 // ----------------------------------- 1552 // -----------------------------------
1524 1553
1525 // The logic contained here is mirrored in Builtins::Generate_Adaptor. 1554 // The logic contained here is mirrored in Builtins::Generate_Adaptor.
1526 // Keep these in sync. 1555 // Keep these in sync.
1527 1556
1528 const bool is_construct = (node->opcode() == IrOpcode::kJSCallConstruct); 1557 const bool is_construct = (node->opcode() == IrOpcode::kJSCallConstruct);
1529 1558
1530 DCHECK(Builtins::HasCppImplementation(builtin_index)); 1559 DCHECK(Builtins::HasCppImplementation(builtin_index));
1531 1560
1561 Zone* zone = jsgraph->zone();
1532 Node* target = NodeProperties::GetValueInput(node, 0); 1562 Node* target = NodeProperties::GetValueInput(node, 0);
1533 Node* new_target = is_construct 1563 Node* new_target = is_construct
1534 ? NodeProperties::GetValueInput(node, arity + 1) 1564 ? NodeProperties::GetValueInput(node, arity + 1)
1535 : jsgraph->UndefinedConstant(); 1565 : jsgraph->UndefinedConstant();
1536 1566
1567 Type* target_type = NodeProperties::GetType(target);
1568 DCHECK(target_type->IsConstant());
1569
1537 // API and CPP builtins are implemented in C++, and we can inline both. 1570 // API and CPP builtins are implemented in C++, and we can inline both.
1538 // CPP builtins create a builtin exit frame, API builtins don't. 1571 // CPP builtins create a builtin exit frame, API builtins don't.
1539 const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index); 1572 const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index);
1540
1541 Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack, 1573 Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack,
1542 has_builtin_exit_frame); 1574 has_builtin_exit_frame);
1543 node->ReplaceInput(0, stub); 1575 node->ReplaceInput(0, stub);
1544 1576
1545 Zone* zone = jsgraph->zone();
1546 if (is_construct) { 1577 if (is_construct) {
1547 // Unify representations between construct and call nodes. 1578 // Unify representations between construct and call nodes.
1548 // Remove new target and add receiver as a stack parameter. 1579 // Remove new target and add receiver as a stack parameter.
1549 Node* receiver = jsgraph->UndefinedConstant(); 1580 Node* receiver = jsgraph->UndefinedConstant();
1550 node->RemoveInput(arity + 1); 1581 node->RemoveInput(arity + 1);
1551 node->InsertInput(zone, 1, receiver); 1582 node->InsertInput(zone, 1, receiver);
1552 } 1583 }
1553 1584
1554 const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver; 1585 Handle<JSFunction> function =
1586 Handle<JSFunction>::cast(target_type->AsConstant()->Value());
1587 const int adapted_arity =
1588 MaybeAdaptArguments(isolate, jsgraph, node, arity, function->shared());
1589
1590 const int argc = adapted_arity + BuiltinArguments::kNumExtraArgsWithReceiver;
1555 Node* argc_node = jsgraph->Int32Constant(argc); 1591 Node* argc_node = jsgraph->Int32Constant(argc);
1556 1592
1557 node->InsertInput(zone, arity + 2, argc_node); 1593 int cursor = adapted_arity + kStubAndReceiver;
1558 node->InsertInput(zone, arity + 3, target); 1594 node->InsertInput(zone, cursor++, argc_node);
1559 node->InsertInput(zone, arity + 4, new_target); 1595 node->InsertInput(zone, cursor++, target);
1596 node->InsertInput(zone, cursor++, new_target);
1560 1597
1561 Address entry = Builtins::CppEntryOf(builtin_index); 1598 Address entry = Builtins::CppEntryOf(builtin_index);
1562 ExternalReference entry_ref(ExternalReference(entry, isolate)); 1599 ExternalReference entry_ref(ExternalReference(entry, isolate));
1563 Node* entry_node = jsgraph->ExternalConstant(entry_ref); 1600 Node* entry_node = jsgraph->ExternalConstant(entry_ref);
1564 1601
1565 node->InsertInput(zone, arity + 5, entry_node); 1602 node->InsertInput(zone, cursor++, entry_node);
1566 node->InsertInput(zone, arity + 6, argc_node); 1603 node->InsertInput(zone, cursor++, argc_node);
1567 1604
1568 static const int kReturnCount = 1; 1605 static const int kReturnCount = 1;
1569 const char* debug_name = Builtins::name(builtin_index); 1606 const char* debug_name = Builtins::name(builtin_index);
1570 Operator::Properties properties = node->op()->properties(); 1607 Operator::Properties properties = node->op()->properties();
1571 CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor( 1608 CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor(
1572 zone, kReturnCount, argc, debug_name, properties, flags); 1609 zone, kReturnCount, argc, debug_name, properties, flags);
1573 1610
1574 NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc)); 1611 NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc));
1575 } 1612 }
1576 1613
(...skipping 14 matching lines...) Expand all
1591 if (target_type->IsConstant() && 1628 if (target_type->IsConstant() &&
1592 target_type->AsConstant()->Value()->IsJSFunction()) { 1629 target_type->AsConstant()->Value()->IsJSFunction()) {
1593 Handle<JSFunction> function = 1630 Handle<JSFunction> function =
1594 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); 1631 Handle<JSFunction>::cast(target_type->AsConstant()->Value());
1595 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 1632 Handle<SharedFunctionInfo> shared(function->shared(), isolate());
1596 const int builtin_index = shared->construct_stub()->builtin_index(); 1633 const int builtin_index = shared->construct_stub()->builtin_index();
1597 const bool is_builtin = (builtin_index != -1); 1634 const bool is_builtin = (builtin_index != -1);
1598 1635
1599 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 1636 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
1600 1637
1601 if (is_builtin && Builtins::HasCppImplementation(builtin_index) && 1638 if (is_builtin && Builtins::HasCppImplementation(builtin_index)) {
1602 (shared->internal_formal_parameter_count() == arity ||
1603 shared->internal_formal_parameter_count() ==
1604 SharedFunctionInfo::kDontAdaptArgumentsSentinel)) {
1605 // Patch {node} to a direct CEntryStub call. 1639 // Patch {node} to a direct CEntryStub call.
1606 1640
1607 // Load the context from the {target}. 1641 // Load the context from the {target}.
1608 Node* context = effect = graph()->NewNode( 1642 Node* context = effect = graph()->NewNode(
1609 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), 1643 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()),
1610 target, effect, control); 1644 target, effect, control);
1611 NodeProperties::ReplaceContextInput(node, context); 1645 NodeProperties::ReplaceContextInput(node, context);
1612 1646
1613 // Update the effect dependency for the {node}. 1647 // Update the effect dependency for the {node}.
1614 NodeProperties::ReplaceEffectInput(node, effect); 1648 NodeProperties::ReplaceEffectInput(node, effect);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 NodeProperties::ReplaceEffectInput(node, effect); 1740 NodeProperties::ReplaceEffectInput(node, effect);
1707 1741
1708 // Compute flags for the call. 1742 // Compute flags for the call.
1709 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 1743 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
1710 if (p.tail_call_mode() == TailCallMode::kAllow) { 1744 if (p.tail_call_mode() == TailCallMode::kAllow) {
1711 flags |= CallDescriptor::kSupportsTailCalls; 1745 flags |= CallDescriptor::kSupportsTailCalls;
1712 } 1746 }
1713 1747
1714 Node* new_target = jsgraph()->UndefinedConstant(); 1748 Node* new_target = jsgraph()->UndefinedConstant();
1715 Node* argument_count = jsgraph()->Int32Constant(arity); 1749 Node* argument_count = jsgraph()->Int32Constant(arity);
1716 if (is_builtin && Builtins::HasCppImplementation(builtin_index) && 1750 if (is_builtin && Builtins::HasCppImplementation(builtin_index)) {
1717 (shared->internal_formal_parameter_count() == arity ||
1718 shared->internal_formal_parameter_count() ==
1719 SharedFunctionInfo::kDontAdaptArgumentsSentinel)) {
1720 // Patch {node} to a direct CEntryStub call. 1751 // Patch {node} to a direct CEntryStub call.
1721 ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); 1752 ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
1722 } else if (shared->internal_formal_parameter_count() == arity || 1753 } else if (shared->internal_formal_parameter_count() == arity ||
1723 shared->internal_formal_parameter_count() == 1754 shared->internal_formal_parameter_count() ==
1724 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 1755 SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
1725 // Patch {node} to a direct call. 1756 // Patch {node} to a direct call.
1726 node->InsertInput(graph()->zone(), arity + 2, new_target); 1757 node->InsertInput(graph()->zone(), arity + 2, new_target);
1727 node->InsertInput(graph()->zone(), arity + 3, argument_count); 1758 node->InsertInput(graph()->zone(), arity + 3, argument_count);
1728 NodeProperties::ChangeOp(node, 1759 NodeProperties::ChangeOp(node,
1729 common()->Call(Linkage::GetJSCallDescriptor( 1760 common()->Call(Linkage::GetJSCallDescriptor(
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 } 2256 }
2226 2257
2227 2258
2228 CompilationDependencies* JSTypedLowering::dependencies() const { 2259 CompilationDependencies* JSTypedLowering::dependencies() const {
2229 return dependencies_; 2260 return dependencies_;
2230 } 2261 }
2231 2262
2232 } // namespace compiler 2263 } // namespace compiler
2233 } // namespace internal 2264 } // namespace internal
2234 } // namespace v8 2265 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698