OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 LoadWithVectorDescriptor::SlotRegister())); | 1580 LoadWithVectorDescriptor::SlotRegister())); |
1581 | 1581 |
1582 NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a4, | 1582 NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a4, |
1583 a5, &miss); | 1583 a5, &miss); |
1584 __ bind(&miss); | 1584 __ bind(&miss); |
1585 PropertyAccessCompiler::TailCallBuiltin( | 1585 PropertyAccessCompiler::TailCallBuiltin( |
1586 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); | 1586 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); |
1587 } | 1587 } |
1588 | 1588 |
1589 | 1589 |
| 1590 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
| 1591 // a1 : function |
| 1592 // a2 : number of parameters (tagged) |
| 1593 // a3 : parameters pointer |
| 1594 |
| 1595 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function())); |
| 1596 DCHECK(a2.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1597 DCHECK(a3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
| 1598 |
| 1599 // Check if the calling frame is an arguments adaptor frame. |
| 1600 Label runtime; |
| 1601 __ ld(a4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 1602 __ ld(a0, MemOperand(a4, StandardFrameConstants::kContextOffset)); |
| 1603 __ Branch(&runtime, ne, a0, |
| 1604 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 1605 |
| 1606 // Patch the arguments.length and the parameters pointer in the current frame. |
| 1607 __ ld(a2, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 1608 __ SmiScale(a7, a2, kPointerSizeLog2); |
| 1609 __ Daddu(a4, a4, Operand(a7)); |
| 1610 __ daddiu(a3, a4, StandardFrameConstants::kCallerSPOffset); |
| 1611 |
| 1612 __ bind(&runtime); |
| 1613 __ Push(a1, a3, a2); |
| 1614 __ TailCallRuntime(Runtime::kNewSloppyArguments); |
| 1615 } |
| 1616 |
| 1617 |
| 1618 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
| 1619 // a1 : function |
| 1620 // a2 : number of parameters (tagged) |
| 1621 // a3 : parameters pointer |
| 1622 // Registers used over whole function: |
| 1623 // a5 : arguments count (tagged) |
| 1624 // a6 : mapped parameter count (tagged) |
| 1625 |
| 1626 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function())); |
| 1627 DCHECK(a2.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1628 DCHECK(a3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
| 1629 |
| 1630 // Check if the calling frame is an arguments adaptor frame. |
| 1631 Label adaptor_frame, try_allocate, runtime; |
| 1632 __ ld(a4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 1633 __ ld(a0, MemOperand(a4, StandardFrameConstants::kContextOffset)); |
| 1634 __ Branch(&adaptor_frame, eq, a0, |
| 1635 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 1636 |
| 1637 // No adaptor, parameter count = argument count. |
| 1638 __ mov(a5, a2); |
| 1639 __ Branch(USE_DELAY_SLOT, &try_allocate); |
| 1640 __ mov(a6, a2); // In delay slot. |
| 1641 |
| 1642 // We have an adaptor frame. Patch the parameters pointer. |
| 1643 __ bind(&adaptor_frame); |
| 1644 __ ld(a5, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 1645 __ SmiScale(t2, a5, kPointerSizeLog2); |
| 1646 __ Daddu(a4, a4, Operand(t2)); |
| 1647 __ Daddu(a3, a4, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 1648 |
| 1649 // a5 = argument count (tagged) |
| 1650 // a6 = parameter count (tagged) |
| 1651 // Compute the mapped parameter count = min(a6, a5) in a6. |
| 1652 __ mov(a6, a2); |
| 1653 __ Branch(&try_allocate, le, a6, Operand(a5)); |
| 1654 __ mov(a6, a5); |
| 1655 |
| 1656 __ bind(&try_allocate); |
| 1657 |
| 1658 // Compute the sizes of backing store, parameter map, and arguments object. |
| 1659 // 1. Parameter map, has 2 extra words containing context and backing store. |
| 1660 const int kParameterMapHeaderSize = |
| 1661 FixedArray::kHeaderSize + 2 * kPointerSize; |
| 1662 // If there are no mapped parameters, we do not need the parameter_map. |
| 1663 Label param_map_size; |
| 1664 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); |
| 1665 __ Branch(USE_DELAY_SLOT, ¶m_map_size, eq, a6, Operand(zero_reg)); |
| 1666 __ mov(t1, zero_reg); // In delay slot: param map size = 0 when a6 == 0. |
| 1667 __ SmiScale(t1, a6, kPointerSizeLog2); |
| 1668 __ daddiu(t1, t1, kParameterMapHeaderSize); |
| 1669 __ bind(¶m_map_size); |
| 1670 |
| 1671 // 2. Backing store. |
| 1672 __ SmiScale(t2, a5, kPointerSizeLog2); |
| 1673 __ Daddu(t1, t1, Operand(t2)); |
| 1674 __ Daddu(t1, t1, Operand(FixedArray::kHeaderSize)); |
| 1675 |
| 1676 // 3. Arguments object. |
| 1677 __ Daddu(t1, t1, Operand(JSSloppyArgumentsObject::kSize)); |
| 1678 |
| 1679 // Do the allocation of all three objects in one go. |
| 1680 __ Allocate(t1, v0, t1, a4, &runtime, TAG_OBJECT); |
| 1681 |
| 1682 // v0 = address of new object(s) (tagged) |
| 1683 // a2 = argument count (smi-tagged) |
| 1684 // Get the arguments boilerplate from the current native context into a4. |
| 1685 const int kNormalOffset = |
| 1686 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); |
| 1687 const int kAliasedOffset = |
| 1688 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); |
| 1689 |
| 1690 __ ld(a4, NativeContextMemOperand()); |
| 1691 Label skip2_ne, skip2_eq; |
| 1692 __ Branch(&skip2_ne, ne, a6, Operand(zero_reg)); |
| 1693 __ ld(a4, MemOperand(a4, kNormalOffset)); |
| 1694 __ bind(&skip2_ne); |
| 1695 |
| 1696 __ Branch(&skip2_eq, eq, a6, Operand(zero_reg)); |
| 1697 __ ld(a4, MemOperand(a4, kAliasedOffset)); |
| 1698 __ bind(&skip2_eq); |
| 1699 |
| 1700 // v0 = address of new object (tagged) |
| 1701 // a2 = argument count (smi-tagged) |
| 1702 // a4 = address of arguments map (tagged) |
| 1703 // a6 = mapped parameter count (tagged) |
| 1704 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset)); |
| 1705 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex); |
| 1706 __ sd(t1, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
| 1707 __ sd(t1, FieldMemOperand(v0, JSObject::kElementsOffset)); |
| 1708 |
| 1709 // Set up the callee in-object property. |
| 1710 __ AssertNotSmi(a1); |
| 1711 __ sd(a1, FieldMemOperand(v0, JSSloppyArgumentsObject::kCalleeOffset)); |
| 1712 |
| 1713 // Use the length (smi tagged) and set that as an in-object property too. |
| 1714 __ AssertSmi(a5); |
| 1715 __ sd(a5, FieldMemOperand(v0, JSSloppyArgumentsObject::kLengthOffset)); |
| 1716 |
| 1717 // Set up the elements pointer in the allocated arguments object. |
| 1718 // If we allocated a parameter map, a4 will point there, otherwise |
| 1719 // it will point to the backing store. |
| 1720 __ Daddu(a4, v0, Operand(JSSloppyArgumentsObject::kSize)); |
| 1721 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); |
| 1722 |
| 1723 // v0 = address of new object (tagged) |
| 1724 // a2 = argument count (tagged) |
| 1725 // a4 = address of parameter map or backing store (tagged) |
| 1726 // a6 = mapped parameter count (tagged) |
| 1727 // Initialize parameter map. If there are no mapped arguments, we're done. |
| 1728 Label skip_parameter_map; |
| 1729 Label skip3; |
| 1730 __ Branch(&skip3, ne, a6, Operand(Smi::FromInt(0))); |
| 1731 // Move backing store address to a1, because it is |
| 1732 // expected there when filling in the unmapped arguments. |
| 1733 __ mov(a1, a4); |
| 1734 __ bind(&skip3); |
| 1735 |
| 1736 __ Branch(&skip_parameter_map, eq, a6, Operand(Smi::FromInt(0))); |
| 1737 |
| 1738 __ LoadRoot(a5, Heap::kSloppyArgumentsElementsMapRootIndex); |
| 1739 __ sd(a5, FieldMemOperand(a4, FixedArray::kMapOffset)); |
| 1740 __ Daddu(a5, a6, Operand(Smi::FromInt(2))); |
| 1741 __ sd(a5, FieldMemOperand(a4, FixedArray::kLengthOffset)); |
| 1742 __ sd(cp, FieldMemOperand(a4, FixedArray::kHeaderSize + 0 * kPointerSize)); |
| 1743 __ SmiScale(t2, a6, kPointerSizeLog2); |
| 1744 __ Daddu(a5, a4, Operand(t2)); |
| 1745 __ Daddu(a5, a5, Operand(kParameterMapHeaderSize)); |
| 1746 __ sd(a5, FieldMemOperand(a4, FixedArray::kHeaderSize + 1 * kPointerSize)); |
| 1747 |
| 1748 // Copy the parameter slots and the holes in the arguments. |
| 1749 // We need to fill in mapped_parameter_count slots. They index the context, |
| 1750 // where parameters are stored in reverse order, at |
| 1751 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |
| 1752 // The mapped parameter thus need to get indices |
| 1753 // MIN_CONTEXT_SLOTS+parameter_count-1 .. |
| 1754 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |
| 1755 // We loop from right to left. |
| 1756 Label parameters_loop, parameters_test; |
| 1757 __ mov(a5, a6); |
| 1758 __ Daddu(t1, a2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); |
| 1759 __ Dsubu(t1, t1, Operand(a6)); |
| 1760 __ LoadRoot(a7, Heap::kTheHoleValueRootIndex); |
| 1761 __ SmiScale(t2, a5, kPointerSizeLog2); |
| 1762 __ Daddu(a1, a4, Operand(t2)); |
| 1763 __ Daddu(a1, a1, Operand(kParameterMapHeaderSize)); |
| 1764 |
| 1765 // a1 = address of backing store (tagged) |
| 1766 // a4 = address of parameter map (tagged) |
| 1767 // a0 = temporary scratch (a.o., for address calculation) |
| 1768 // t1 = loop variable (tagged) |
| 1769 // a7 = the hole value |
| 1770 __ jmp(¶meters_test); |
| 1771 |
| 1772 __ bind(¶meters_loop); |
| 1773 __ Dsubu(a5, a5, Operand(Smi::FromInt(1))); |
| 1774 __ SmiScale(a0, a5, kPointerSizeLog2); |
| 1775 __ Daddu(a0, a0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); |
| 1776 __ Daddu(t2, a4, a0); |
| 1777 __ sd(t1, MemOperand(t2)); |
| 1778 __ Dsubu(a0, a0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); |
| 1779 __ Daddu(t2, a1, a0); |
| 1780 __ sd(a7, MemOperand(t2)); |
| 1781 __ Daddu(t1, t1, Operand(Smi::FromInt(1))); |
| 1782 __ bind(¶meters_test); |
| 1783 __ Branch(¶meters_loop, ne, a5, Operand(Smi::FromInt(0))); |
| 1784 |
| 1785 // Restore t1 = argument count (tagged). |
| 1786 __ ld(a5, FieldMemOperand(v0, JSSloppyArgumentsObject::kLengthOffset)); |
| 1787 |
| 1788 __ bind(&skip_parameter_map); |
| 1789 // v0 = address of new object (tagged) |
| 1790 // a1 = address of backing store (tagged) |
| 1791 // a5 = argument count (tagged) |
| 1792 // a6 = mapped parameter count (tagged) |
| 1793 // t1 = scratch |
| 1794 // Copy arguments header and remaining slots (if there are any). |
| 1795 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex); |
| 1796 __ sd(t1, FieldMemOperand(a1, FixedArray::kMapOffset)); |
| 1797 __ sd(a5, FieldMemOperand(a1, FixedArray::kLengthOffset)); |
| 1798 |
| 1799 Label arguments_loop, arguments_test; |
| 1800 __ SmiScale(t2, a6, kPointerSizeLog2); |
| 1801 __ Dsubu(a3, a3, Operand(t2)); |
| 1802 __ jmp(&arguments_test); |
| 1803 |
| 1804 __ bind(&arguments_loop); |
| 1805 __ Dsubu(a3, a3, Operand(kPointerSize)); |
| 1806 __ ld(a4, MemOperand(a3, 0)); |
| 1807 __ SmiScale(t2, a6, kPointerSizeLog2); |
| 1808 __ Daddu(t1, a1, Operand(t2)); |
| 1809 __ sd(a4, FieldMemOperand(t1, FixedArray::kHeaderSize)); |
| 1810 __ Daddu(a6, a6, Operand(Smi::FromInt(1))); |
| 1811 |
| 1812 __ bind(&arguments_test); |
| 1813 __ Branch(&arguments_loop, lt, a6, Operand(a5)); |
| 1814 |
| 1815 // Return. |
| 1816 __ Ret(); |
| 1817 |
| 1818 // Do the runtime call to allocate the arguments object. |
| 1819 // a5 = argument count (tagged) |
| 1820 __ bind(&runtime); |
| 1821 __ Push(a1, a3, a5); |
| 1822 __ TailCallRuntime(Runtime::kNewSloppyArguments); |
| 1823 } |
| 1824 |
| 1825 |
1590 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1826 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1591 // Return address is in ra. | 1827 // Return address is in ra. |
1592 Label slow; | 1828 Label slow; |
1593 | 1829 |
1594 Register receiver = LoadDescriptor::ReceiverRegister(); | 1830 Register receiver = LoadDescriptor::ReceiverRegister(); |
1595 Register key = LoadDescriptor::NameRegister(); | 1831 Register key = LoadDescriptor::NameRegister(); |
1596 | 1832 |
1597 // Check that the key is an array index, that is Uint32. | 1833 // Check that the key is an array index, that is Uint32. |
1598 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); | 1834 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); |
1599 __ Branch(&slow, ne, t0, Operand(zero_reg)); | 1835 __ Branch(&slow, ne, t0, Operand(zero_reg)); |
(...skipping 3315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4915 __ Push(a0, a2, a1); | 5151 __ Push(a0, a2, a1); |
4916 __ CallRuntime(Runtime::kAllocateInNewSpace); | 5152 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4917 __ Pop(a0, a2); | 5153 __ Pop(a0, a2); |
4918 __ SmiUntag(a0); | 5154 __ SmiUntag(a0); |
4919 } | 5155 } |
4920 __ jmp(&done_allocate); | 5156 __ jmp(&done_allocate); |
4921 } | 5157 } |
4922 } | 5158 } |
4923 | 5159 |
4924 | 5160 |
4925 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { | |
4926 // ----------- S t a t e ------------- | |
4927 // -- a1 : function | |
4928 // -- cp : context | |
4929 // -- fp : frame pointer | |
4930 // -- ra : return address | |
4931 // ----------------------------------- | |
4932 __ AssertFunction(a1); | |
4933 | |
4934 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. | |
4935 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | |
4936 __ lw(a2, | |
4937 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset)); | |
4938 __ Lsa(a3, fp, a2, kPointerSizeLog2); | |
4939 __ Addu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset)); | |
4940 __ SmiTag(a2); | |
4941 | |
4942 // a1 : function | |
4943 // a2 : number of parameters (tagged) | |
4944 // a3 : parameters pointer | |
4945 // Registers used over whole function: | |
4946 // a5 : arguments count (tagged) | |
4947 // a6 : mapped parameter count (tagged) | |
4948 | |
4949 // Check if the calling frame is an arguments adaptor frame. | |
4950 Label adaptor_frame, try_allocate, runtime; | |
4951 __ ld(a4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
4952 __ ld(a0, MemOperand(a4, StandardFrameConstants::kContextOffset)); | |
4953 __ Branch(&adaptor_frame, eq, a0, | |
4954 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
4955 | |
4956 // No adaptor, parameter count = argument count. | |
4957 __ mov(a5, a2); | |
4958 __ Branch(USE_DELAY_SLOT, &try_allocate); | |
4959 __ mov(a6, a2); // In delay slot. | |
4960 | |
4961 // We have an adaptor frame. Patch the parameters pointer. | |
4962 __ bind(&adaptor_frame); | |
4963 __ ld(a5, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
4964 __ SmiScale(t2, a5, kPointerSizeLog2); | |
4965 __ Daddu(a4, a4, Operand(t2)); | |
4966 __ Daddu(a3, a4, Operand(StandardFrameConstants::kCallerSPOffset)); | |
4967 | |
4968 // a5 = argument count (tagged) | |
4969 // a6 = parameter count (tagged) | |
4970 // Compute the mapped parameter count = min(a6, a5) in a6. | |
4971 __ mov(a6, a2); | |
4972 __ Branch(&try_allocate, le, a6, Operand(a5)); | |
4973 __ mov(a6, a5); | |
4974 | |
4975 __ bind(&try_allocate); | |
4976 | |
4977 // Compute the sizes of backing store, parameter map, and arguments object. | |
4978 // 1. Parameter map, has 2 extra words containing context and backing store. | |
4979 const int kParameterMapHeaderSize = | |
4980 FixedArray::kHeaderSize + 2 * kPointerSize; | |
4981 // If there are no mapped parameters, we do not need the parameter_map. | |
4982 Label param_map_size; | |
4983 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); | |
4984 __ Branch(USE_DELAY_SLOT, ¶m_map_size, eq, a6, Operand(zero_reg)); | |
4985 __ mov(t1, zero_reg); // In delay slot: param map size = 0 when a6 == 0. | |
4986 __ SmiScale(t1, a6, kPointerSizeLog2); | |
4987 __ daddiu(t1, t1, kParameterMapHeaderSize); | |
4988 __ bind(¶m_map_size); | |
4989 | |
4990 // 2. Backing store. | |
4991 __ SmiScale(t2, a5, kPointerSizeLog2); | |
4992 __ Daddu(t1, t1, Operand(t2)); | |
4993 __ Daddu(t1, t1, Operand(FixedArray::kHeaderSize)); | |
4994 | |
4995 // 3. Arguments object. | |
4996 __ Daddu(t1, t1, Operand(JSSloppyArgumentsObject::kSize)); | |
4997 | |
4998 // Do the allocation of all three objects in one go. | |
4999 __ Allocate(t1, v0, t1, a4, &runtime, TAG_OBJECT); | |
5000 | |
5001 // v0 = address of new object(s) (tagged) | |
5002 // a2 = argument count (smi-tagged) | |
5003 // Get the arguments boilerplate from the current native context into a4. | |
5004 const int kNormalOffset = | |
5005 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); | |
5006 const int kAliasedOffset = | |
5007 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); | |
5008 | |
5009 __ ld(a4, NativeContextMemOperand()); | |
5010 Label skip2_ne, skip2_eq; | |
5011 __ Branch(&skip2_ne, ne, a6, Operand(zero_reg)); | |
5012 __ ld(a4, MemOperand(a4, kNormalOffset)); | |
5013 __ bind(&skip2_ne); | |
5014 | |
5015 __ Branch(&skip2_eq, eq, a6, Operand(zero_reg)); | |
5016 __ ld(a4, MemOperand(a4, kAliasedOffset)); | |
5017 __ bind(&skip2_eq); | |
5018 | |
5019 // v0 = address of new object (tagged) | |
5020 // a2 = argument count (smi-tagged) | |
5021 // a4 = address of arguments map (tagged) | |
5022 // a6 = mapped parameter count (tagged) | |
5023 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset)); | |
5024 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex); | |
5025 __ sd(t1, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | |
5026 __ sd(t1, FieldMemOperand(v0, JSObject::kElementsOffset)); | |
5027 | |
5028 // Set up the callee in-object property. | |
5029 __ AssertNotSmi(a1); | |
5030 __ sd(a1, FieldMemOperand(v0, JSSloppyArgumentsObject::kCalleeOffset)); | |
5031 | |
5032 // Use the length (smi tagged) and set that as an in-object property too. | |
5033 __ AssertSmi(a5); | |
5034 __ sd(a5, FieldMemOperand(v0, JSSloppyArgumentsObject::kLengthOffset)); | |
5035 | |
5036 // Set up the elements pointer in the allocated arguments object. | |
5037 // If we allocated a parameter map, a4 will point there, otherwise | |
5038 // it will point to the backing store. | |
5039 __ Daddu(a4, v0, Operand(JSSloppyArgumentsObject::kSize)); | |
5040 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); | |
5041 | |
5042 // v0 = address of new object (tagged) | |
5043 // a2 = argument count (tagged) | |
5044 // a4 = address of parameter map or backing store (tagged) | |
5045 // a6 = mapped parameter count (tagged) | |
5046 // Initialize parameter map. If there are no mapped arguments, we're done. | |
5047 Label skip_parameter_map; | |
5048 Label skip3; | |
5049 __ Branch(&skip3, ne, a6, Operand(Smi::FromInt(0))); | |
5050 // Move backing store address to a1, because it is | |
5051 // expected there when filling in the unmapped arguments. | |
5052 __ mov(a1, a4); | |
5053 __ bind(&skip3); | |
5054 | |
5055 __ Branch(&skip_parameter_map, eq, a6, Operand(Smi::FromInt(0))); | |
5056 | |
5057 __ LoadRoot(a5, Heap::kSloppyArgumentsElementsMapRootIndex); | |
5058 __ sd(a5, FieldMemOperand(a4, FixedArray::kMapOffset)); | |
5059 __ Daddu(a5, a6, Operand(Smi::FromInt(2))); | |
5060 __ sd(a5, FieldMemOperand(a4, FixedArray::kLengthOffset)); | |
5061 __ sd(cp, FieldMemOperand(a4, FixedArray::kHeaderSize + 0 * kPointerSize)); | |
5062 __ SmiScale(t2, a6, kPointerSizeLog2); | |
5063 __ Daddu(a5, a4, Operand(t2)); | |
5064 __ Daddu(a5, a5, Operand(kParameterMapHeaderSize)); | |
5065 __ sd(a5, FieldMemOperand(a4, FixedArray::kHeaderSize + 1 * kPointerSize)); | |
5066 | |
5067 // Copy the parameter slots and the holes in the arguments. | |
5068 // We need to fill in mapped_parameter_count slots. They index the context, | |
5069 // where parameters are stored in reverse order, at | |
5070 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | |
5071 // The mapped parameter thus need to get indices | |
5072 // MIN_CONTEXT_SLOTS+parameter_count-1 .. | |
5073 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | |
5074 // We loop from right to left. | |
5075 Label parameters_loop, parameters_test; | |
5076 __ mov(a5, a6); | |
5077 __ Daddu(t1, a2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); | |
5078 __ Dsubu(t1, t1, Operand(a6)); | |
5079 __ LoadRoot(a7, Heap::kTheHoleValueRootIndex); | |
5080 __ SmiScale(t2, a5, kPointerSizeLog2); | |
5081 __ Daddu(a1, a4, Operand(t2)); | |
5082 __ Daddu(a1, a1, Operand(kParameterMapHeaderSize)); | |
5083 | |
5084 // a1 = address of backing store (tagged) | |
5085 // a4 = address of parameter map (tagged) | |
5086 // a0 = temporary scratch (a.o., for address calculation) | |
5087 // t1 = loop variable (tagged) | |
5088 // a7 = the hole value | |
5089 __ jmp(¶meters_test); | |
5090 | |
5091 __ bind(¶meters_loop); | |
5092 __ Dsubu(a5, a5, Operand(Smi::FromInt(1))); | |
5093 __ SmiScale(a0, a5, kPointerSizeLog2); | |
5094 __ Daddu(a0, a0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); | |
5095 __ Daddu(t2, a4, a0); | |
5096 __ sd(t1, MemOperand(t2)); | |
5097 __ Dsubu(a0, a0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); | |
5098 __ Daddu(t2, a1, a0); | |
5099 __ sd(a7, MemOperand(t2)); | |
5100 __ Daddu(t1, t1, Operand(Smi::FromInt(1))); | |
5101 __ bind(¶meters_test); | |
5102 __ Branch(¶meters_loop, ne, a5, Operand(Smi::FromInt(0))); | |
5103 | |
5104 // Restore t1 = argument count (tagged). | |
5105 __ ld(a5, FieldMemOperand(v0, JSSloppyArgumentsObject::kLengthOffset)); | |
5106 | |
5107 __ bind(&skip_parameter_map); | |
5108 // v0 = address of new object (tagged) | |
5109 // a1 = address of backing store (tagged) | |
5110 // a5 = argument count (tagged) | |
5111 // a6 = mapped parameter count (tagged) | |
5112 // t1 = scratch | |
5113 // Copy arguments header and remaining slots (if there are any). | |
5114 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex); | |
5115 __ sd(t1, FieldMemOperand(a1, FixedArray::kMapOffset)); | |
5116 __ sd(a5, FieldMemOperand(a1, FixedArray::kLengthOffset)); | |
5117 | |
5118 Label arguments_loop, arguments_test; | |
5119 __ SmiScale(t2, a6, kPointerSizeLog2); | |
5120 __ Dsubu(a3, a3, Operand(t2)); | |
5121 __ jmp(&arguments_test); | |
5122 | |
5123 __ bind(&arguments_loop); | |
5124 __ Dsubu(a3, a3, Operand(kPointerSize)); | |
5125 __ ld(a4, MemOperand(a3, 0)); | |
5126 __ SmiScale(t2, a6, kPointerSizeLog2); | |
5127 __ Daddu(t1, a1, Operand(t2)); | |
5128 __ sd(a4, FieldMemOperand(t1, FixedArray::kHeaderSize)); | |
5129 __ Daddu(a6, a6, Operand(Smi::FromInt(1))); | |
5130 | |
5131 __ bind(&arguments_test); | |
5132 __ Branch(&arguments_loop, lt, a6, Operand(a5)); | |
5133 | |
5134 // Return. | |
5135 __ Ret(); | |
5136 | |
5137 // Do the runtime call to allocate the arguments object. | |
5138 // a5 = argument count (tagged) | |
5139 __ bind(&runtime); | |
5140 __ Push(a1, a3, a5); | |
5141 __ TailCallRuntime(Runtime::kNewSloppyArguments); | |
5142 } | |
5143 | |
5144 | |
5145 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { | 5161 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
5146 // ----------- S t a t e ------------- | 5162 // ----------- S t a t e ------------- |
5147 // -- a1 : function | 5163 // -- a1 : function |
5148 // -- cp : context | 5164 // -- cp : context |
5149 // -- fp : frame pointer | 5165 // -- fp : frame pointer |
5150 // -- ra : return address | 5166 // -- ra : return address |
5151 // ----------------------------------- | 5167 // ----------------------------------- |
5152 __ AssertFunction(a1); | 5168 __ AssertFunction(a1); |
5153 | 5169 |
5154 // For Ignition we need to skip all possible handler/stub frames until | 5170 // For Ignition we need to skip all possible handler/stub frames until |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5711 return_value_operand, NULL); | 5727 return_value_operand, NULL); |
5712 } | 5728 } |
5713 | 5729 |
5714 | 5730 |
5715 #undef __ | 5731 #undef __ |
5716 | 5732 |
5717 } // namespace internal | 5733 } // namespace internal |
5718 } // namespace v8 | 5734 } // namespace v8 |
5719 | 5735 |
5720 #endif // V8_TARGET_ARCH_MIPS64 | 5736 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |