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 |
1629 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1930 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1630 // Return address is in lr. | 1931 // Return address is in lr. |
1631 Label slow; | 1932 Label slow; |
1632 | 1933 |
1633 Register receiver = LoadDescriptor::ReceiverRegister(); | 1934 Register receiver = LoadDescriptor::ReceiverRegister(); |
1634 Register key = LoadDescriptor::NameRegister(); | 1935 Register key = LoadDescriptor::NameRegister(); |
1635 | 1936 |
1636 // Check that the key is an array index, that is Uint32. | 1937 // Check that the key is an array index, that is Uint32. |
1637 __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow); | 1938 __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow); |
1638 | 1939 |
(...skipping 3354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4993 __ CallRuntime(Runtime::kAllocateInNewSpace); | 5294 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4994 __ Mov(x3, x0); | 5295 __ Mov(x3, x0); |
4995 __ Pop(x2, x0); | 5296 __ Pop(x2, x0); |
4996 __ SmiUntag(x0); | 5297 __ SmiUntag(x0); |
4997 } | 5298 } |
4998 __ B(&done_allocate); | 5299 __ B(&done_allocate); |
4999 } | 5300 } |
5000 } | 5301 } |
5001 | 5302 |
5002 | 5303 |
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 | |
5285 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { | 5304 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
5286 // ----------- S t a t e ------------- | 5305 // ----------- S t a t e ------------- |
5287 // -- x1 : function | 5306 // -- x1 : function |
5288 // -- cp : context | 5307 // -- cp : context |
5289 // -- fp : frame pointer | 5308 // -- fp : frame pointer |
5290 // -- lr : return address | 5309 // -- lr : return address |
5291 // ----------------------------------- | 5310 // ----------------------------------- |
5292 __ AssertFunction(x1); | 5311 __ AssertFunction(x1); |
5293 | 5312 |
5294 // For Ignition we need to skip all possible handler/stub frames until | 5313 // 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... |
5892 return_value_operand, NULL); | 5911 return_value_operand, NULL); |
5893 } | 5912 } |
5894 | 5913 |
5895 | 5914 |
5896 #undef __ | 5915 #undef __ |
5897 | 5916 |
5898 } // namespace internal | 5917 } // namespace internal |
5899 } // namespace v8 | 5918 } // namespace v8 |
5900 | 5919 |
5901 #endif // V8_TARGET_ARCH_ARM64 | 5920 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |