| 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/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 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 __ StoreRoot(scratch, Heap::kInstanceofCacheFunctionRootIndex); | 1619 __ StoreRoot(scratch, Heap::kInstanceofCacheFunctionRootIndex); |
| 1620 __ TailCallRuntime(Runtime::kHasInPrototypeChain); | 1620 __ TailCallRuntime(Runtime::kHasInPrototypeChain); |
| 1621 | 1621 |
| 1622 // Slow-case: Call the %InstanceOf runtime function. | 1622 // Slow-case: Call the %InstanceOf runtime function. |
| 1623 __ bind(&slow_case); | 1623 __ bind(&slow_case); |
| 1624 __ Push(object, function); | 1624 __ Push(object, function); |
| 1625 __ TailCallRuntime(Runtime::kInstanceOf); | 1625 __ TailCallRuntime(Runtime::kInstanceOf); |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 | 1628 |
| 1629 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | |
| 1630 // x1 : function | |
| 1631 // x2 : number of parameters (tagged) | |
| 1632 // x3 : parameters pointer | |
| 1633 | |
| 1634 DCHECK(x1.is(ArgumentsAccessNewDescriptor::function())); | |
| 1635 DCHECK(x2.is(ArgumentsAccessNewDescriptor::parameter_count())); | |
| 1636 DCHECK(x3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | |
| 1637 | |
| 1638 // Check if the calling frame is an arguments adaptor frame. | |
| 1639 Label runtime; | |
| 1640 Register caller_fp = x10; | |
| 1641 __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
| 1642 // Load and untag the context. | |
| 1643 __ Ldr(w11, UntagSmiMemOperand(caller_fp, | |
| 1644 StandardFrameConstants::kContextOffset)); | |
| 1645 __ Cmp(w11, StackFrame::ARGUMENTS_ADAPTOR); | |
| 1646 __ B(ne, &runtime); | |
| 1647 | |
| 1648 // Patch the arguments.length and parameters pointer in the current frame. | |
| 1649 __ Ldr(x2, | |
| 1650 MemOperand(caller_fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
| 1651 __ Add(x3, caller_fp, Operand::UntagSmiAndScale(x2, kPointerSizeLog2)); | |
| 1652 __ Add(x3, x3, StandardFrameConstants::kCallerSPOffset); | |
| 1653 | |
| 1654 __ Bind(&runtime); | |
| 1655 __ Push(x1, x3, x2); | |
| 1656 __ TailCallRuntime(Runtime::kNewSloppyArguments); | |
| 1657 } | |
| 1658 | |
| 1659 | |
| 1660 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | |
| 1661 // x1 : function | |
| 1662 // x2 : number of parameters (tagged) | |
| 1663 // x3 : parameters pointer | |
| 1664 // | |
| 1665 // Returns pointer to result object in x0. | |
| 1666 | |
| 1667 DCHECK(x1.is(ArgumentsAccessNewDescriptor::function())); | |
| 1668 DCHECK(x2.is(ArgumentsAccessNewDescriptor::parameter_count())); | |
| 1669 DCHECK(x3.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | |
| 1670 | |
| 1671 // Make an untagged copy of the parameter count. | |
| 1672 // Note: arg_count_smi is an alias of param_count_smi. | |
| 1673 Register function = x1; | |
| 1674 Register arg_count_smi = x2; | |
| 1675 Register param_count_smi = x2; | |
| 1676 Register recv_arg = x3; | |
| 1677 Register param_count = x7; | |
| 1678 __ SmiUntag(param_count, param_count_smi); | |
| 1679 | |
| 1680 // Check if the calling frame is an arguments adaptor frame. | |
| 1681 Register caller_fp = x11; | |
| 1682 Register caller_ctx = x12; | |
| 1683 Label runtime; | |
| 1684 Label adaptor_frame, try_allocate; | |
| 1685 __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | |
| 1686 __ Ldr(caller_ctx, MemOperand(caller_fp, | |
| 1687 StandardFrameConstants::kContextOffset)); | |
| 1688 __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | |
| 1689 __ B(eq, &adaptor_frame); | |
| 1690 | |
| 1691 // No adaptor, parameter count = argument count. | |
| 1692 | |
| 1693 // x1 function function pointer | |
| 1694 // x2 arg_count_smi number of function arguments (smi) | |
| 1695 // x3 recv_arg pointer to receiver arguments | |
| 1696 // x4 mapped_params number of mapped params, min(params, args) (uninit) | |
| 1697 // x7 param_count number of function parameters | |
| 1698 // x11 caller_fp caller's frame pointer | |
| 1699 // x14 arg_count number of function arguments (uninit) | |
| 1700 | |
| 1701 Register arg_count = x14; | |
| 1702 Register mapped_params = x4; | |
| 1703 __ Mov(arg_count, param_count); | |
| 1704 __ Mov(mapped_params, param_count); | |
| 1705 __ B(&try_allocate); | |
| 1706 | |
| 1707 // We have an adaptor frame. Patch the parameters pointer. | |
| 1708 __ Bind(&adaptor_frame); | |
| 1709 __ Ldr(arg_count_smi, | |
| 1710 MemOperand(caller_fp, | |
| 1711 ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
| 1712 __ SmiUntag(arg_count, arg_count_smi); | |
| 1713 __ Add(x10, caller_fp, Operand(arg_count, LSL, kPointerSizeLog2)); | |
| 1714 __ Add(recv_arg, x10, StandardFrameConstants::kCallerSPOffset); | |
| 1715 | |
| 1716 // Compute the mapped parameter count = min(param_count, arg_count) | |
| 1717 __ Cmp(param_count, arg_count); | |
| 1718 __ Csel(mapped_params, param_count, arg_count, lt); | |
| 1719 | |
| 1720 __ Bind(&try_allocate); | |
| 1721 | |
| 1722 // x0 alloc_obj pointer to allocated objects: param map, backing | |
| 1723 // store, arguments (uninit) | |
| 1724 // x1 function function pointer | |
| 1725 // x2 arg_count_smi number of function arguments (smi) | |
| 1726 // x3 recv_arg pointer to receiver arguments | |
| 1727 // x4 mapped_params number of mapped parameters, min(params, args) | |
| 1728 // x7 param_count number of function parameters | |
| 1729 // x10 size size of objects to allocate (uninit) | |
| 1730 // x14 arg_count number of function arguments | |
| 1731 | |
| 1732 // Compute the size of backing store, parameter map, and arguments object. | |
| 1733 // 1. Parameter map, has two extra words containing context and backing | |
| 1734 // store. | |
| 1735 const int kParameterMapHeaderSize = | |
| 1736 FixedArray::kHeaderSize + 2 * kPointerSize; | |
| 1737 | |
| 1738 // Calculate the parameter map size, assuming it exists. | |
| 1739 Register size = x10; | |
| 1740 __ Mov(size, Operand(mapped_params, LSL, kPointerSizeLog2)); | |
| 1741 __ Add(size, size, kParameterMapHeaderSize); | |
| 1742 | |
| 1743 // If there are no mapped parameters, set the running size total to zero. | |
| 1744 // Otherwise, use the parameter map size calculated earlier. | |
| 1745 __ Cmp(mapped_params, 0); | |
| 1746 __ CzeroX(size, eq); | |
| 1747 | |
| 1748 // 2. Add the size of the backing store and arguments object. | |
| 1749 __ Add(size, size, Operand(arg_count, LSL, kPointerSizeLog2)); | |
| 1750 __ Add(size, size, FixedArray::kHeaderSize + JSSloppyArgumentsObject::kSize); | |
| 1751 | |
| 1752 // Do the allocation of all three objects in one go. Assign this to x0, as it | |
| 1753 // will be returned to the caller. | |
| 1754 Register alloc_obj = x0; | |
| 1755 __ Allocate(size, alloc_obj, x11, x12, &runtime, TAG_OBJECT); | |
| 1756 | |
| 1757 // Get the arguments boilerplate from the current (global) context. | |
| 1758 | |
| 1759 // x0 alloc_obj pointer to allocated objects (param map, backing | |
| 1760 // store, arguments) | |
| 1761 // x1 function function pointer | |
| 1762 // x2 arg_count_smi number of function arguments (smi) | |
| 1763 // x3 recv_arg pointer to receiver arguments | |
| 1764 // x4 mapped_params number of mapped parameters, min(params, args) | |
| 1765 // x7 param_count number of function parameters | |
| 1766 // x11 sloppy_args_map offset to args (or aliased args) map (uninit) | |
| 1767 // x14 arg_count number of function arguments | |
| 1768 | |
| 1769 Register global_ctx = x10; | |
| 1770 Register sloppy_args_map = x11; | |
| 1771 Register aliased_args_map = x10; | |
| 1772 __ Ldr(global_ctx, NativeContextMemOperand()); | |
| 1773 | |
| 1774 __ Ldr(sloppy_args_map, | |
| 1775 ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | |
| 1776 __ Ldr( | |
| 1777 aliased_args_map, | |
| 1778 ContextMemOperand(global_ctx, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)); | |
| 1779 __ Cmp(mapped_params, 0); | |
| 1780 __ CmovX(sloppy_args_map, aliased_args_map, ne); | |
| 1781 | |
| 1782 // Copy the JS object part. | |
| 1783 __ Str(sloppy_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset)); | |
| 1784 __ LoadRoot(x10, Heap::kEmptyFixedArrayRootIndex); | |
| 1785 __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset)); | |
| 1786 __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); | |
| 1787 | |
| 1788 // Set up the callee in-object property. | |
| 1789 __ AssertNotSmi(function); | |
| 1790 __ Str(function, | |
| 1791 FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kCalleeOffset)); | |
| 1792 | |
| 1793 // Use the length and set that as an in-object property. | |
| 1794 __ Str(arg_count_smi, | |
| 1795 FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kLengthOffset)); | |
| 1796 | |
| 1797 // Set up the elements pointer in the allocated arguments object. | |
| 1798 // If we allocated a parameter map, "elements" will point there, otherwise | |
| 1799 // it will point to the backing store. | |
| 1800 | |
| 1801 // x0 alloc_obj pointer to allocated objects (param map, backing | |
| 1802 // store, arguments) | |
| 1803 // x1 function function pointer | |
| 1804 // x2 arg_count_smi number of function arguments (smi) | |
| 1805 // x3 recv_arg pointer to receiver arguments | |
| 1806 // x4 mapped_params number of mapped parameters, min(params, args) | |
| 1807 // x5 elements pointer to parameter map or backing store (uninit) | |
| 1808 // x6 backing_store pointer to backing store (uninit) | |
| 1809 // x7 param_count number of function parameters | |
| 1810 // x14 arg_count number of function arguments | |
| 1811 | |
| 1812 Register elements = x5; | |
| 1813 __ Add(elements, alloc_obj, JSSloppyArgumentsObject::kSize); | |
| 1814 __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); | |
| 1815 | |
| 1816 // Initialize parameter map. If there are no mapped arguments, we're done. | |
| 1817 Label skip_parameter_map; | |
| 1818 __ Cmp(mapped_params, 0); | |
| 1819 // Set up backing store address, because it is needed later for filling in | |
| 1820 // the unmapped arguments. | |
| 1821 Register backing_store = x6; | |
| 1822 __ CmovX(backing_store, elements, eq); | |
| 1823 __ B(eq, &skip_parameter_map); | |
| 1824 | |
| 1825 __ LoadRoot(x10, Heap::kSloppyArgumentsElementsMapRootIndex); | |
| 1826 __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset)); | |
| 1827 __ Add(x10, mapped_params, 2); | |
| 1828 __ SmiTag(x10); | |
| 1829 __ Str(x10, FieldMemOperand(elements, FixedArray::kLengthOffset)); | |
| 1830 __ Str(cp, FieldMemOperand(elements, | |
| 1831 FixedArray::kHeaderSize + 0 * kPointerSize)); | |
| 1832 __ Add(x10, elements, Operand(mapped_params, LSL, kPointerSizeLog2)); | |
| 1833 __ Add(x10, x10, kParameterMapHeaderSize); | |
| 1834 __ Str(x10, FieldMemOperand(elements, | |
| 1835 FixedArray::kHeaderSize + 1 * kPointerSize)); | |
| 1836 | |
| 1837 // Copy the parameter slots and the holes in the arguments. | |
| 1838 // We need to fill in mapped_parameter_count slots. Then index the context, | |
| 1839 // where parameters are stored in reverse order, at: | |
| 1840 // | |
| 1841 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS + parameter_count - 1 | |
| 1842 // | |
| 1843 // The mapped parameter thus needs to get indices: | |
| 1844 // | |
| 1845 // MIN_CONTEXT_SLOTS + parameter_count - 1 .. | |
| 1846 // MIN_CONTEXT_SLOTS + parameter_count - mapped_parameter_count | |
| 1847 // | |
| 1848 // We loop from right to left. | |
| 1849 | |
| 1850 // x0 alloc_obj pointer to allocated objects (param map, backing | |
| 1851 // store, arguments) | |
| 1852 // x1 function function pointer | |
| 1853 // x2 arg_count_smi number of function arguments (smi) | |
| 1854 // x3 recv_arg pointer to receiver arguments | |
| 1855 // x4 mapped_params number of mapped parameters, min(params, args) | |
| 1856 // x5 elements pointer to parameter map or backing store (uninit) | |
| 1857 // x6 backing_store pointer to backing store (uninit) | |
| 1858 // x7 param_count number of function parameters | |
| 1859 // x11 loop_count parameter loop counter (uninit) | |
| 1860 // x12 index parameter index (smi, uninit) | |
| 1861 // x13 the_hole hole value (uninit) | |
| 1862 // x14 arg_count number of function arguments | |
| 1863 | |
| 1864 Register loop_count = x11; | |
| 1865 Register index = x12; | |
| 1866 Register the_hole = x13; | |
| 1867 Label parameters_loop, parameters_test; | |
| 1868 __ Mov(loop_count, mapped_params); | |
| 1869 __ Add(index, param_count, static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | |
| 1870 __ Sub(index, index, mapped_params); | |
| 1871 __ SmiTag(index); | |
| 1872 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); | |
| 1873 __ Add(backing_store, elements, Operand(loop_count, LSL, kPointerSizeLog2)); | |
| 1874 __ Add(backing_store, backing_store, kParameterMapHeaderSize); | |
| 1875 | |
| 1876 __ B(¶meters_test); | |
| 1877 | |
| 1878 __ Bind(¶meters_loop); | |
| 1879 __ Sub(loop_count, loop_count, 1); | |
| 1880 __ Mov(x10, Operand(loop_count, LSL, kPointerSizeLog2)); | |
| 1881 __ Add(x10, x10, kParameterMapHeaderSize - kHeapObjectTag); | |
| 1882 __ Str(index, MemOperand(elements, x10)); | |
| 1883 __ Sub(x10, x10, kParameterMapHeaderSize - FixedArray::kHeaderSize); | |
| 1884 __ Str(the_hole, MemOperand(backing_store, x10)); | |
| 1885 __ Add(index, index, Smi::FromInt(1)); | |
| 1886 __ Bind(¶meters_test); | |
| 1887 __ Cbnz(loop_count, ¶meters_loop); | |
| 1888 | |
| 1889 __ Bind(&skip_parameter_map); | |
| 1890 // Copy arguments header and remaining slots (if there are any.) | |
| 1891 __ LoadRoot(x10, Heap::kFixedArrayMapRootIndex); | |
| 1892 __ Str(x10, FieldMemOperand(backing_store, FixedArray::kMapOffset)); | |
| 1893 __ Str(arg_count_smi, FieldMemOperand(backing_store, | |
| 1894 FixedArray::kLengthOffset)); | |
| 1895 | |
| 1896 // x0 alloc_obj pointer to allocated objects (param map, backing | |
| 1897 // store, arguments) | |
| 1898 // x1 function function pointer | |
| 1899 // x2 arg_count_smi number of function arguments (smi) | |
| 1900 // x3 recv_arg pointer to receiver arguments | |
| 1901 // x4 mapped_params number of mapped parameters, min(params, args) | |
| 1902 // x6 backing_store pointer to backing store (uninit) | |
| 1903 // x14 arg_count number of function arguments | |
| 1904 | |
| 1905 Label arguments_loop, arguments_test; | |
| 1906 __ Mov(x10, mapped_params); | |
| 1907 __ Sub(recv_arg, recv_arg, Operand(x10, LSL, kPointerSizeLog2)); | |
| 1908 __ B(&arguments_test); | |
| 1909 | |
| 1910 __ Bind(&arguments_loop); | |
| 1911 __ Sub(recv_arg, recv_arg, kPointerSize); | |
| 1912 __ Ldr(x11, MemOperand(recv_arg)); | |
| 1913 __ Add(x12, backing_store, Operand(x10, LSL, kPointerSizeLog2)); | |
| 1914 __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize)); | |
| 1915 __ Add(x10, x10, 1); | |
| 1916 | |
| 1917 __ Bind(&arguments_test); | |
| 1918 __ Cmp(x10, arg_count); | |
| 1919 __ B(lt, &arguments_loop); | |
| 1920 | |
| 1921 __ Ret(); | |
| 1922 | |
| 1923 // Do the runtime call to allocate the arguments object. | |
| 1924 __ Bind(&runtime); | |
| 1925 __ Push(function, recv_arg, arg_count_smi); | |
| 1926 __ TailCallRuntime(Runtime::kNewSloppyArguments); | |
| 1927 } | |
| 1928 | |
| 1929 | |
| 1930 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1629 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
| 1931 // Return address is in lr. | 1630 // Return address is in lr. |
| 1932 Label slow; | 1631 Label slow; |
| 1933 | 1632 |
| 1934 Register receiver = LoadDescriptor::ReceiverRegister(); | 1633 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 1935 Register key = LoadDescriptor::NameRegister(); | 1634 Register key = LoadDescriptor::NameRegister(); |
| 1936 | 1635 |
| 1937 // Check that the key is an array index, that is Uint32. | 1636 // Check that the key is an array index, that is Uint32. |
| 1938 __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow); | 1637 __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow); |
| 1939 | 1638 |
| (...skipping 3354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5294 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4993 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5295 __ Mov(x3, x0); | 4994 __ Mov(x3, x0); |
| 5296 __ Pop(x2, x0); | 4995 __ Pop(x2, x0); |
| 5297 __ SmiUntag(x0); | 4996 __ SmiUntag(x0); |
| 5298 } | 4997 } |
| 5299 __ B(&done_allocate); | 4998 __ B(&done_allocate); |
| 5300 } | 4999 } |
| 5301 } | 5000 } |
| 5302 | 5001 |
| 5303 | 5002 |
| 5003 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { |
| 5004 // ----------- S t a t e ------------- |
| 5005 // -- x1 : function |
| 5006 // -- cp : context |
| 5007 // -- fp : frame pointer |
| 5008 // -- lr : return address |
| 5009 // ----------------------------------- |
| 5010 __ AssertFunction(x1); |
| 5011 |
| 5012 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. |
| 5013 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 5014 __ Ldrsw( |
| 5015 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 5016 __ Add(x3, fp, Operand(x2, LSL, kPointerSizeLog2)); |
| 5017 __ Add(x3, x3, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 5018 __ SmiTag(x2); |
| 5019 |
| 5020 // x1 : function |
| 5021 // x2 : number of parameters (tagged) |
| 5022 // x3 : parameters pointer |
| 5023 // |
| 5024 // Returns pointer to result object in x0. |
| 5025 |
| 5026 // Make an untagged copy of the parameter count. |
| 5027 // Note: arg_count_smi is an alias of param_count_smi. |
| 5028 Register function = x1; |
| 5029 Register arg_count_smi = x2; |
| 5030 Register param_count_smi = x2; |
| 5031 Register recv_arg = x3; |
| 5032 Register param_count = x7; |
| 5033 __ SmiUntag(param_count, param_count_smi); |
| 5034 |
| 5035 // Check if the calling frame is an arguments adaptor frame. |
| 5036 Register caller_fp = x11; |
| 5037 Register caller_ctx = x12; |
| 5038 Label runtime; |
| 5039 Label adaptor_frame, try_allocate; |
| 5040 __ Ldr(caller_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 5041 __ Ldr(caller_ctx, MemOperand(caller_fp, |
| 5042 StandardFrameConstants::kContextOffset)); |
| 5043 __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 5044 __ B(eq, &adaptor_frame); |
| 5045 |
| 5046 // No adaptor, parameter count = argument count. |
| 5047 |
| 5048 // x1 function function pointer |
| 5049 // x2 arg_count_smi number of function arguments (smi) |
| 5050 // x3 recv_arg pointer to receiver arguments |
| 5051 // x4 mapped_params number of mapped params, min(params, args) (uninit) |
| 5052 // x7 param_count number of function parameters |
| 5053 // x11 caller_fp caller's frame pointer |
| 5054 // x14 arg_count number of function arguments (uninit) |
| 5055 |
| 5056 Register arg_count = x14; |
| 5057 Register mapped_params = x4; |
| 5058 __ Mov(arg_count, param_count); |
| 5059 __ Mov(mapped_params, param_count); |
| 5060 __ B(&try_allocate); |
| 5061 |
| 5062 // We have an adaptor frame. Patch the parameters pointer. |
| 5063 __ Bind(&adaptor_frame); |
| 5064 __ Ldr(arg_count_smi, |
| 5065 MemOperand(caller_fp, |
| 5066 ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 5067 __ SmiUntag(arg_count, arg_count_smi); |
| 5068 __ Add(x10, caller_fp, Operand(arg_count, LSL, kPointerSizeLog2)); |
| 5069 __ Add(recv_arg, x10, StandardFrameConstants::kCallerSPOffset); |
| 5070 |
| 5071 // Compute the mapped parameter count = min(param_count, arg_count) |
| 5072 __ Cmp(param_count, arg_count); |
| 5073 __ Csel(mapped_params, param_count, arg_count, lt); |
| 5074 |
| 5075 __ Bind(&try_allocate); |
| 5076 |
| 5077 // x0 alloc_obj pointer to allocated objects: param map, backing |
| 5078 // store, arguments (uninit) |
| 5079 // x1 function function pointer |
| 5080 // x2 arg_count_smi number of function arguments (smi) |
| 5081 // x3 recv_arg pointer to receiver arguments |
| 5082 // x4 mapped_params number of mapped parameters, min(params, args) |
| 5083 // x7 param_count number of function parameters |
| 5084 // x10 size size of objects to allocate (uninit) |
| 5085 // x14 arg_count number of function arguments |
| 5086 |
| 5087 // Compute the size of backing store, parameter map, and arguments object. |
| 5088 // 1. Parameter map, has two extra words containing context and backing |
| 5089 // store. |
| 5090 const int kParameterMapHeaderSize = |
| 5091 FixedArray::kHeaderSize + 2 * kPointerSize; |
| 5092 |
| 5093 // Calculate the parameter map size, assuming it exists. |
| 5094 Register size = x10; |
| 5095 __ Mov(size, Operand(mapped_params, LSL, kPointerSizeLog2)); |
| 5096 __ Add(size, size, kParameterMapHeaderSize); |
| 5097 |
| 5098 // If there are no mapped parameters, set the running size total to zero. |
| 5099 // Otherwise, use the parameter map size calculated earlier. |
| 5100 __ Cmp(mapped_params, 0); |
| 5101 __ CzeroX(size, eq); |
| 5102 |
| 5103 // 2. Add the size of the backing store and arguments object. |
| 5104 __ Add(size, size, Operand(arg_count, LSL, kPointerSizeLog2)); |
| 5105 __ Add(size, size, FixedArray::kHeaderSize + JSSloppyArgumentsObject::kSize); |
| 5106 |
| 5107 // Do the allocation of all three objects in one go. Assign this to x0, as it |
| 5108 // will be returned to the caller. |
| 5109 Register alloc_obj = x0; |
| 5110 __ Allocate(size, alloc_obj, x11, x12, &runtime, TAG_OBJECT); |
| 5111 |
| 5112 // Get the arguments boilerplate from the current (global) context. |
| 5113 |
| 5114 // x0 alloc_obj pointer to allocated objects (param map, backing |
| 5115 // store, arguments) |
| 5116 // x1 function function pointer |
| 5117 // x2 arg_count_smi number of function arguments (smi) |
| 5118 // x3 recv_arg pointer to receiver arguments |
| 5119 // x4 mapped_params number of mapped parameters, min(params, args) |
| 5120 // x7 param_count number of function parameters |
| 5121 // x11 sloppy_args_map offset to args (or aliased args) map (uninit) |
| 5122 // x14 arg_count number of function arguments |
| 5123 |
| 5124 Register global_ctx = x10; |
| 5125 Register sloppy_args_map = x11; |
| 5126 Register aliased_args_map = x10; |
| 5127 __ Ldr(global_ctx, NativeContextMemOperand()); |
| 5128 |
| 5129 __ Ldr(sloppy_args_map, |
| 5130 ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
| 5131 __ Ldr( |
| 5132 aliased_args_map, |
| 5133 ContextMemOperand(global_ctx, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)); |
| 5134 __ Cmp(mapped_params, 0); |
| 5135 __ CmovX(sloppy_args_map, aliased_args_map, ne); |
| 5136 |
| 5137 // Copy the JS object part. |
| 5138 __ Str(sloppy_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset)); |
| 5139 __ LoadRoot(x10, Heap::kEmptyFixedArrayRootIndex); |
| 5140 __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset)); |
| 5141 __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); |
| 5142 |
| 5143 // Set up the callee in-object property. |
| 5144 __ AssertNotSmi(function); |
| 5145 __ Str(function, |
| 5146 FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kCalleeOffset)); |
| 5147 |
| 5148 // Use the length and set that as an in-object property. |
| 5149 __ Str(arg_count_smi, |
| 5150 FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kLengthOffset)); |
| 5151 |
| 5152 // Set up the elements pointer in the allocated arguments object. |
| 5153 // If we allocated a parameter map, "elements" will point there, otherwise |
| 5154 // it will point to the backing store. |
| 5155 |
| 5156 // x0 alloc_obj pointer to allocated objects (param map, backing |
| 5157 // store, arguments) |
| 5158 // x1 function function pointer |
| 5159 // x2 arg_count_smi number of function arguments (smi) |
| 5160 // x3 recv_arg pointer to receiver arguments |
| 5161 // x4 mapped_params number of mapped parameters, min(params, args) |
| 5162 // x5 elements pointer to parameter map or backing store (uninit) |
| 5163 // x6 backing_store pointer to backing store (uninit) |
| 5164 // x7 param_count number of function parameters |
| 5165 // x14 arg_count number of function arguments |
| 5166 |
| 5167 Register elements = x5; |
| 5168 __ Add(elements, alloc_obj, JSSloppyArgumentsObject::kSize); |
| 5169 __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); |
| 5170 |
| 5171 // Initialize parameter map. If there are no mapped arguments, we're done. |
| 5172 Label skip_parameter_map; |
| 5173 __ Cmp(mapped_params, 0); |
| 5174 // Set up backing store address, because it is needed later for filling in |
| 5175 // the unmapped arguments. |
| 5176 Register backing_store = x6; |
| 5177 __ CmovX(backing_store, elements, eq); |
| 5178 __ B(eq, &skip_parameter_map); |
| 5179 |
| 5180 __ LoadRoot(x10, Heap::kSloppyArgumentsElementsMapRootIndex); |
| 5181 __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset)); |
| 5182 __ Add(x10, mapped_params, 2); |
| 5183 __ SmiTag(x10); |
| 5184 __ Str(x10, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| 5185 __ Str(cp, FieldMemOperand(elements, |
| 5186 FixedArray::kHeaderSize + 0 * kPointerSize)); |
| 5187 __ Add(x10, elements, Operand(mapped_params, LSL, kPointerSizeLog2)); |
| 5188 __ Add(x10, x10, kParameterMapHeaderSize); |
| 5189 __ Str(x10, FieldMemOperand(elements, |
| 5190 FixedArray::kHeaderSize + 1 * kPointerSize)); |
| 5191 |
| 5192 // Copy the parameter slots and the holes in the arguments. |
| 5193 // We need to fill in mapped_parameter_count slots. Then index the context, |
| 5194 // where parameters are stored in reverse order, at: |
| 5195 // |
| 5196 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS + parameter_count - 1 |
| 5197 // |
| 5198 // The mapped parameter thus needs to get indices: |
| 5199 // |
| 5200 // MIN_CONTEXT_SLOTS + parameter_count - 1 .. |
| 5201 // MIN_CONTEXT_SLOTS + parameter_count - mapped_parameter_count |
| 5202 // |
| 5203 // We loop from right to left. |
| 5204 |
| 5205 // x0 alloc_obj pointer to allocated objects (param map, backing |
| 5206 // store, arguments) |
| 5207 // x1 function function pointer |
| 5208 // x2 arg_count_smi number of function arguments (smi) |
| 5209 // x3 recv_arg pointer to receiver arguments |
| 5210 // x4 mapped_params number of mapped parameters, min(params, args) |
| 5211 // x5 elements pointer to parameter map or backing store (uninit) |
| 5212 // x6 backing_store pointer to backing store (uninit) |
| 5213 // x7 param_count number of function parameters |
| 5214 // x11 loop_count parameter loop counter (uninit) |
| 5215 // x12 index parameter index (smi, uninit) |
| 5216 // x13 the_hole hole value (uninit) |
| 5217 // x14 arg_count number of function arguments |
| 5218 |
| 5219 Register loop_count = x11; |
| 5220 Register index = x12; |
| 5221 Register the_hole = x13; |
| 5222 Label parameters_loop, parameters_test; |
| 5223 __ Mov(loop_count, mapped_params); |
| 5224 __ Add(index, param_count, static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 5225 __ Sub(index, index, mapped_params); |
| 5226 __ SmiTag(index); |
| 5227 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); |
| 5228 __ Add(backing_store, elements, Operand(loop_count, LSL, kPointerSizeLog2)); |
| 5229 __ Add(backing_store, backing_store, kParameterMapHeaderSize); |
| 5230 |
| 5231 __ B(¶meters_test); |
| 5232 |
| 5233 __ Bind(¶meters_loop); |
| 5234 __ Sub(loop_count, loop_count, 1); |
| 5235 __ Mov(x10, Operand(loop_count, LSL, kPointerSizeLog2)); |
| 5236 __ Add(x10, x10, kParameterMapHeaderSize - kHeapObjectTag); |
| 5237 __ Str(index, MemOperand(elements, x10)); |
| 5238 __ Sub(x10, x10, kParameterMapHeaderSize - FixedArray::kHeaderSize); |
| 5239 __ Str(the_hole, MemOperand(backing_store, x10)); |
| 5240 __ Add(index, index, Smi::FromInt(1)); |
| 5241 __ Bind(¶meters_test); |
| 5242 __ Cbnz(loop_count, ¶meters_loop); |
| 5243 |
| 5244 __ Bind(&skip_parameter_map); |
| 5245 // Copy arguments header and remaining slots (if there are any.) |
| 5246 __ LoadRoot(x10, Heap::kFixedArrayMapRootIndex); |
| 5247 __ Str(x10, FieldMemOperand(backing_store, FixedArray::kMapOffset)); |
| 5248 __ Str(arg_count_smi, FieldMemOperand(backing_store, |
| 5249 FixedArray::kLengthOffset)); |
| 5250 |
| 5251 // x0 alloc_obj pointer to allocated objects (param map, backing |
| 5252 // store, arguments) |
| 5253 // x1 function function pointer |
| 5254 // x2 arg_count_smi number of function arguments (smi) |
| 5255 // x3 recv_arg pointer to receiver arguments |
| 5256 // x4 mapped_params number of mapped parameters, min(params, args) |
| 5257 // x6 backing_store pointer to backing store (uninit) |
| 5258 // x14 arg_count number of function arguments |
| 5259 |
| 5260 Label arguments_loop, arguments_test; |
| 5261 __ Mov(x10, mapped_params); |
| 5262 __ Sub(recv_arg, recv_arg, Operand(x10, LSL, kPointerSizeLog2)); |
| 5263 __ B(&arguments_test); |
| 5264 |
| 5265 __ Bind(&arguments_loop); |
| 5266 __ Sub(recv_arg, recv_arg, kPointerSize); |
| 5267 __ Ldr(x11, MemOperand(recv_arg)); |
| 5268 __ Add(x12, backing_store, Operand(x10, LSL, kPointerSizeLog2)); |
| 5269 __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize)); |
| 5270 __ Add(x10, x10, 1); |
| 5271 |
| 5272 __ Bind(&arguments_test); |
| 5273 __ Cmp(x10, arg_count); |
| 5274 __ B(lt, &arguments_loop); |
| 5275 |
| 5276 __ Ret(); |
| 5277 |
| 5278 // Do the runtime call to allocate the arguments object. |
| 5279 __ Bind(&runtime); |
| 5280 __ Push(function, recv_arg, arg_count_smi); |
| 5281 __ TailCallRuntime(Runtime::kNewSloppyArguments); |
| 5282 } |
| 5283 |
| 5284 |
| 5304 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { | 5285 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
| 5305 // ----------- S t a t e ------------- | 5286 // ----------- S t a t e ------------- |
| 5306 // -- x1 : function | 5287 // -- x1 : function |
| 5307 // -- cp : context | 5288 // -- cp : context |
| 5308 // -- fp : frame pointer | 5289 // -- fp : frame pointer |
| 5309 // -- lr : return address | 5290 // -- lr : return address |
| 5310 // ----------------------------------- | 5291 // ----------------------------------- |
| 5311 __ AssertFunction(x1); | 5292 __ AssertFunction(x1); |
| 5312 | 5293 |
| 5313 // For Ignition we need to skip all possible handler/stub frames until | 5294 // For Ignition we need to skip all possible handler/stub frames until |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5911 return_value_operand, NULL); | 5892 return_value_operand, NULL); |
| 5912 } | 5893 } |
| 5913 | 5894 |
| 5914 | 5895 |
| 5915 #undef __ | 5896 #undef __ |
| 5916 | 5897 |
| 5917 } // namespace internal | 5898 } // namespace internal |
| 5918 } // namespace v8 | 5899 } // namespace v8 |
| 5919 | 5900 |
| 5920 #endif // V8_TARGET_ARCH_ARM64 | 5901 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |