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 |