OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 RelocInfo::CODE_TARGET); | 1463 RelocInfo::CODE_TARGET); |
1464 __ Bind(&dont_adapt_args); | 1464 __ Bind(&dont_adapt_args); |
1465 | 1465 |
1466 __ Ldr(x3, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 1466 __ Ldr(x3, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
1467 ParameterCount expected(0); | 1467 ParameterCount expected(0); |
1468 __ InvokeCode(x3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1468 __ InvokeCode(x3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1469 } | 1469 } |
1470 | 1470 |
1471 | 1471 |
1472 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1472 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1473 const int vectorOffset, |
1473 const int argumentsOffset, | 1474 const int argumentsOffset, |
1474 const int indexOffset, | 1475 const int indexOffset, |
1475 const int limitOffset) { | 1476 const int limitOffset) { |
1476 Label entry, loop; | 1477 Label entry, loop; |
1477 Register receiver = LoadDescriptor::ReceiverRegister(); | 1478 Register receiver = LoadDescriptor::ReceiverRegister(); |
1478 Register key = LoadDescriptor::NameRegister(); | 1479 Register key = LoadDescriptor::NameRegister(); |
1479 Register slot = LoadDescriptor::SlotRegister(); | 1480 Register slot = LoadDescriptor::SlotRegister(); |
1480 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1481 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
1481 | 1482 |
1482 __ Ldr(key, MemOperand(fp, indexOffset)); | 1483 __ Ldr(key, MemOperand(fp, indexOffset)); |
1483 __ B(&entry); | 1484 __ B(&entry); |
1484 | 1485 |
1485 // Load the current argument from the arguments array. | 1486 // Load the current argument from the arguments array. |
1486 __ Bind(&loop); | 1487 __ Bind(&loop); |
1487 __ Ldr(receiver, MemOperand(fp, argumentsOffset)); | 1488 __ Ldr(receiver, MemOperand(fp, argumentsOffset)); |
1488 | 1489 |
1489 // Use inline caching to speed up access to arguments. | 1490 // Use inline caching to speed up access to arguments. |
1490 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1491 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
1491 FeedbackVectorSpec spec(0, 1, kinds); | 1492 __ Mov(slot, Operand(Smi::FromInt(slot_index))); |
1492 Handle<TypeFeedbackVector> feedback_vector = | 1493 __ Ldr(vector, MemOperand(fp, vectorOffset)); |
1493 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
1494 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
1495 __ Mov(slot, Smi::FromInt(index)); | |
1496 __ Mov(vector, feedback_vector); | |
1497 Handle<Code> ic = | 1494 Handle<Code> ic = |
1498 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1495 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
1499 __ Call(ic, RelocInfo::CODE_TARGET); | 1496 __ Call(ic, RelocInfo::CODE_TARGET); |
1500 | 1497 |
1501 // Push the nth argument. | 1498 // Push the nth argument. |
1502 __ Push(x0); | 1499 __ Push(x0); |
1503 | 1500 |
1504 __ Ldr(key, MemOperand(fp, indexOffset)); | 1501 __ Ldr(key, MemOperand(fp, indexOffset)); |
1505 __ Add(key, key, Smi::FromInt(1)); | 1502 __ Add(key, key, Smi::FromInt(1)); |
1506 __ Str(key, MemOperand(fp, indexOffset)); | 1503 __ Str(key, MemOperand(fp, indexOffset)); |
(...skipping 14 matching lines...) Expand all Loading... |
1521 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { | 1518 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { |
1522 const int kFormalParameters = targetIsArgument ? 3 : 2; | 1519 const int kFormalParameters = targetIsArgument ? 3 : 2; |
1523 const int kStackSize = kFormalParameters + 1; | 1520 const int kStackSize = kFormalParameters + 1; |
1524 | 1521 |
1525 { | 1522 { |
1526 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1523 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1527 | 1524 |
1528 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1525 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1529 const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1526 const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1530 const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1527 const int kFunctionOffset = kReceiverOffset + kPointerSize; |
1531 const int kIndexOffset = | 1528 const int kVectorOffset = |
1532 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1529 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
1533 const int kLimitOffset = | 1530 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1534 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1531 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1535 | 1532 |
1536 Register args = x12; | 1533 Register args = x12; |
1537 Register receiver = x14; | 1534 Register receiver = x14; |
1538 Register function = x15; | 1535 Register function = x15; |
| 1536 Register apply_function = x1; |
| 1537 |
| 1538 // Push the vector. |
| 1539 __ Ldr( |
| 1540 apply_function, |
| 1541 FieldMemOperand(apply_function, JSFunction::kSharedFunctionInfoOffset)); |
| 1542 __ Ldr(apply_function, |
| 1543 FieldMemOperand(apply_function, |
| 1544 SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1545 __ Push(apply_function); |
1539 | 1546 |
1540 // Get the length of the arguments via a builtin call. | 1547 // Get the length of the arguments via a builtin call. |
1541 __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 1548 __ Ldr(function, MemOperand(fp, kFunctionOffset)); |
1542 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); | 1549 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); |
1543 __ Push(function, args); | 1550 __ Push(function, args); |
1544 if (targetIsArgument) { | 1551 if (targetIsArgument) { |
1545 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1552 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1546 } else { | 1553 } else { |
1547 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1554 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1548 } | 1555 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 | 1604 |
1598 __ Bind(&use_global_proxy); | 1605 __ Bind(&use_global_proxy); |
1599 __ Ldr(x10, GlobalObjectMemOperand()); | 1606 __ Ldr(x10, GlobalObjectMemOperand()); |
1600 __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset)); | 1607 __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset)); |
1601 | 1608 |
1602 // Push the receiver | 1609 // Push the receiver |
1603 __ Bind(&push_receiver); | 1610 __ Bind(&push_receiver); |
1604 __ Push(receiver); | 1611 __ Push(receiver); |
1605 | 1612 |
1606 // Copy all arguments from the array to the stack. | 1613 // Copy all arguments from the array to the stack. |
1607 Generate_PushAppliedArguments( | 1614 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1608 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1615 kIndexOffset, kLimitOffset); |
1609 | 1616 |
1610 // At the end of the loop, the number of arguments is stored in 'current', | 1617 // At the end of the loop, the number of arguments is stored in 'current', |
1611 // represented as a smi. | 1618 // represented as a smi. |
1612 | 1619 |
1613 function = x1; // From now on we want the function to be kept in x1; | 1620 function = x1; // From now on we want the function to be kept in x1; |
1614 __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 1621 __ Ldr(function, MemOperand(fp, kFunctionOffset)); |
1615 | 1622 |
1616 // Call the function. | 1623 // Call the function. |
1617 Label call_proxy; | 1624 Label call_proxy; |
1618 ParameterCount actual(x0); | 1625 ParameterCount actual(x0); |
(...skipping 22 matching lines...) Expand all Loading... |
1641 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1648 static void Generate_ConstructHelper(MacroAssembler* masm) { |
1642 const int kFormalParameters = 3; | 1649 const int kFormalParameters = 3; |
1643 const int kStackSize = kFormalParameters + 1; | 1650 const int kStackSize = kFormalParameters + 1; |
1644 | 1651 |
1645 { | 1652 { |
1646 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1653 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1647 | 1654 |
1648 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1655 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1649 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1656 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1650 const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1657 const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
1651 | 1658 const int kVectorOffset = |
1652 const int kIndexOffset = | 1659 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
1653 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1660 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1654 const int kLimitOffset = | 1661 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1655 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1656 | 1662 |
1657 // Is x11 safe to use? | 1663 // Is x11 safe to use? |
1658 Register newTarget = x11; | 1664 Register newTarget = x11; |
1659 Register args = x12; | 1665 Register args = x12; |
1660 Register function = x15; | 1666 Register function = x15; |
| 1667 Register construct_function = x1; |
| 1668 |
| 1669 // Push the vector. |
| 1670 __ Ldr(construct_function, |
| 1671 FieldMemOperand(construct_function, |
| 1672 JSFunction::kSharedFunctionInfoOffset)); |
| 1673 __ Ldr(construct_function, |
| 1674 FieldMemOperand(construct_function, |
| 1675 SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1676 __ Push(construct_function); |
1661 | 1677 |
1662 // If newTarget is not supplied, set it to constructor | 1678 // If newTarget is not supplied, set it to constructor |
1663 Label validate_arguments; | 1679 Label validate_arguments; |
1664 __ Ldr(x0, MemOperand(fp, kNewTargetOffset)); | 1680 __ Ldr(x0, MemOperand(fp, kNewTargetOffset)); |
1665 __ CompareRoot(x0, Heap::kUndefinedValueRootIndex); | 1681 __ CompareRoot(x0, Heap::kUndefinedValueRootIndex); |
1666 __ B(ne, &validate_arguments); | 1682 __ B(ne, &validate_arguments); |
1667 __ Ldr(x0, MemOperand(fp, kFunctionOffset)); | 1683 __ Ldr(x0, MemOperand(fp, kFunctionOffset)); |
1668 __ Str(x0, MemOperand(fp, kNewTargetOffset)); | 1684 __ Str(x0, MemOperand(fp, kNewTargetOffset)); |
1669 | 1685 |
1670 // Validate arguments | 1686 // Validate arguments |
1671 __ Bind(&validate_arguments); | 1687 __ Bind(&validate_arguments); |
1672 __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 1688 __ Ldr(function, MemOperand(fp, kFunctionOffset)); |
1673 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); | 1689 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); |
1674 __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset)); | 1690 __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset)); |
1675 __ Push(function, args, newTarget); | 1691 __ Push(function, args, newTarget); |
1676 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1692 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1677 Register argc = x0; | 1693 Register argc = x0; |
1678 | 1694 |
1679 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged); | 1695 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged); |
1680 | 1696 |
1681 // Push current limit and index & constructor function as callee. | 1697 // Push current limit and index & constructor function as callee. |
1682 __ Mov(x1, 0); // Initial index. | 1698 __ Mov(x1, 0); // Initial index. |
1683 __ Push(argc, x1, function); | 1699 __ Push(argc, x1, function); |
1684 | 1700 |
1685 // Copy all arguments from the array to the stack. | 1701 // Copy all arguments from the array to the stack. |
1686 Generate_PushAppliedArguments( | 1702 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1687 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1703 kIndexOffset, kLimitOffset); |
1688 | 1704 |
1689 // Use undefined feedback vector | 1705 // Use undefined feedback vector |
1690 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); | 1706 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); |
1691 __ Ldr(x1, MemOperand(fp, kFunctionOffset)); | 1707 __ Ldr(x1, MemOperand(fp, kFunctionOffset)); |
1692 __ Ldr(x4, MemOperand(fp, kNewTargetOffset)); | 1708 __ Ldr(x4, MemOperand(fp, kNewTargetOffset)); |
1693 | 1709 |
1694 // Call the function. | 1710 // Call the function. |
1695 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1711 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
1696 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1712 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
1697 | 1713 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1931 } | 1947 } |
1932 } | 1948 } |
1933 | 1949 |
1934 | 1950 |
1935 #undef __ | 1951 #undef __ |
1936 | 1952 |
1937 } // namespace internal | 1953 } // namespace internal |
1938 } // namespace v8 | 1954 } // namespace v8 |
1939 | 1955 |
1940 #endif // V8_TARGET_ARCH_ARM | 1956 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |