OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/assembler-inl.h" | 7 #include "src/assembler-inl.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/counters.h" | 9 #include "src/counters.h" |
10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" |
(...skipping 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1763 | 1763 |
1764 // static | 1764 // static |
1765 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { | 1765 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { |
1766 // ----------- S t a t e ------------- | 1766 // ----------- S t a t e ------------- |
1767 // -- r0 : argc | 1767 // -- r0 : argc |
1768 // -- sp[0] : argArray | 1768 // -- sp[0] : argArray |
1769 // -- sp[4] : thisArg | 1769 // -- sp[4] : thisArg |
1770 // -- sp[8] : receiver | 1770 // -- sp[8] : receiver |
1771 // ----------------------------------- | 1771 // ----------------------------------- |
1772 | 1772 |
1773 // 1. Load receiver into r1, argArray into r0 (if present), remove all | 1773 // 1. Load receiver into r1, argArray into r2 (if present), remove all |
1774 // arguments from the stack (including the receiver), and push thisArg (if | 1774 // arguments from the stack (including the receiver), and push thisArg (if |
1775 // present) instead. | 1775 // present) instead. |
1776 { | 1776 { |
1777 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 1777 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
1778 __ mov(r3, r2); | 1778 __ mov(r2, r5); |
1779 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // receiver | 1779 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // receiver |
1780 __ sub(r4, r0, Operand(1), SetCC); | 1780 __ sub(r4, r0, Operand(1), SetCC); |
1781 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // thisArg | 1781 __ ldr(r5, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // thisArg |
1782 __ sub(r4, r4, Operand(1), SetCC, ge); | 1782 __ sub(r4, r4, Operand(1), SetCC, ge); |
1783 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argArray | 1783 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argArray |
1784 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); | 1784 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); |
1785 __ str(r2, MemOperand(sp, 0)); | 1785 __ str(r5, MemOperand(sp, 0)); |
1786 __ mov(r0, r3); | |
1787 } | 1786 } |
1788 | 1787 |
1789 // ----------- S t a t e ------------- | 1788 // ----------- S t a t e ------------- |
1790 // -- r0 : argArray | 1789 // -- r2 : argArray |
1791 // -- r1 : receiver | 1790 // -- r1 : receiver |
1792 // -- sp[0] : thisArg | 1791 // -- sp[0] : thisArg |
1793 // ----------------------------------- | 1792 // ----------------------------------- |
1794 | 1793 |
1795 // 2. Make sure the receiver is actually callable. | 1794 // 2. Make sure the receiver is actually callable. |
1796 Label receiver_not_callable; | 1795 Label receiver_not_callable; |
1797 __ JumpIfSmi(r1, &receiver_not_callable); | 1796 __ JumpIfSmi(r1, &receiver_not_callable); |
1798 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1797 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1799 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | 1798 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); |
1800 __ tst(r4, Operand(1 << Map::kIsCallable)); | 1799 __ tst(r4, Operand(1 << Map::kIsCallable)); |
1801 __ b(eq, &receiver_not_callable); | 1800 __ b(eq, &receiver_not_callable); |
1802 | 1801 |
1803 // 3. Tail call with no arguments if argArray is null or undefined. | 1802 // 3. Tail call with no arguments if argArray is null or undefined. |
1804 Label no_arguments; | 1803 Label no_arguments; |
1805 __ JumpIfRoot(r0, Heap::kNullValueRootIndex, &no_arguments); | 1804 __ JumpIfRoot(r2, Heap::kNullValueRootIndex, &no_arguments); |
1806 __ JumpIfRoot(r0, Heap::kUndefinedValueRootIndex, &no_arguments); | 1805 __ JumpIfRoot(r2, Heap::kUndefinedValueRootIndex, &no_arguments); |
1807 | 1806 |
1808 // 4a. Apply the receiver to the given argArray (passing undefined for | 1807 // 4a. Apply the receiver to the given argArray. |
1809 // new.target). | 1808 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(), |
1810 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 1809 RelocInfo::CODE_TARGET); |
1811 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | |
1812 | 1810 |
1813 // 4b. The argArray is either null or undefined, so we tail call without any | 1811 // 4b. The argArray is either null or undefined, so we tail call without any |
1814 // arguments to the receiver. | 1812 // arguments to the receiver. |
1815 __ bind(&no_arguments); | 1813 __ bind(&no_arguments); |
1816 { | 1814 { |
1817 __ mov(r0, Operand(0)); | 1815 __ mov(r0, Operand(0)); |
1818 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1816 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1819 } | 1817 } |
1820 | 1818 |
1821 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1819 // 4c. The receiver is not callable, throw an appropriate TypeError. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1871 | 1869 |
1872 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1870 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
1873 // ----------- S t a t e ------------- | 1871 // ----------- S t a t e ------------- |
1874 // -- r0 : argc | 1872 // -- r0 : argc |
1875 // -- sp[0] : argumentsList | 1873 // -- sp[0] : argumentsList |
1876 // -- sp[4] : thisArgument | 1874 // -- sp[4] : thisArgument |
1877 // -- sp[8] : target | 1875 // -- sp[8] : target |
1878 // -- sp[12] : receiver | 1876 // -- sp[12] : receiver |
1879 // ----------------------------------- | 1877 // ----------------------------------- |
1880 | 1878 |
1881 // 1. Load target into r1 (if present), argumentsList into r0 (if present), | 1879 // 1. Load target into r1 (if present), argumentsList into r2 (if present), |
1882 // remove all arguments from the stack (including the receiver), and push | 1880 // remove all arguments from the stack (including the receiver), and push |
1883 // thisArgument (if present) instead. | 1881 // thisArgument (if present) instead. |
1884 { | 1882 { |
1885 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); | 1883 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); |
| 1884 __ mov(r5, r1); |
1886 __ mov(r2, r1); | 1885 __ mov(r2, r1); |
1887 __ mov(r3, r1); | |
1888 __ sub(r4, r0, Operand(1), SetCC); | 1886 __ sub(r4, r0, Operand(1), SetCC); |
1889 __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // target | 1887 __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // target |
1890 __ sub(r4, r4, Operand(1), SetCC, ge); | 1888 __ sub(r4, r4, Operand(1), SetCC, ge); |
1891 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // thisArgument | 1889 __ ldr(r5, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // thisArgument |
1892 __ sub(r4, r4, Operand(1), SetCC, ge); | 1890 __ sub(r4, r4, Operand(1), SetCC, ge); |
1893 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argumentsList | 1891 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argumentsList |
1894 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); | 1892 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); |
1895 __ str(r2, MemOperand(sp, 0)); | 1893 __ str(r5, MemOperand(sp, 0)); |
1896 __ mov(r0, r3); | |
1897 } | 1894 } |
1898 | 1895 |
1899 // ----------- S t a t e ------------- | 1896 // ----------- S t a t e ------------- |
1900 // -- r0 : argumentsList | 1897 // -- r2 : argumentsList |
1901 // -- r1 : target | 1898 // -- r1 : target |
1902 // -- sp[0] : thisArgument | 1899 // -- sp[0] : thisArgument |
1903 // ----------------------------------- | 1900 // ----------------------------------- |
1904 | 1901 |
1905 // 2. Make sure the target is actually callable. | 1902 // 2. Make sure the target is actually callable. |
1906 Label target_not_callable; | 1903 Label target_not_callable; |
1907 __ JumpIfSmi(r1, &target_not_callable); | 1904 __ JumpIfSmi(r1, &target_not_callable); |
1908 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1905 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1909 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | 1906 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); |
1910 __ tst(r4, Operand(1 << Map::kIsCallable)); | 1907 __ tst(r4, Operand(1 << Map::kIsCallable)); |
1911 __ b(eq, &target_not_callable); | 1908 __ b(eq, &target_not_callable); |
1912 | 1909 |
1913 // 3a. Apply the target to the given argumentsList (passing undefined for | 1910 // 3a. Apply the target to the given argumentsList. |
1914 // new.target). | 1911 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(), |
1915 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 1912 RelocInfo::CODE_TARGET); |
1916 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | |
1917 | 1913 |
1918 // 3b. The target is not callable, throw an appropriate TypeError. | 1914 // 3b. The target is not callable, throw an appropriate TypeError. |
1919 __ bind(&target_not_callable); | 1915 __ bind(&target_not_callable); |
1920 { | 1916 { |
1921 __ str(r1, MemOperand(sp, 0)); | 1917 __ str(r1, MemOperand(sp, 0)); |
1922 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1918 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1923 } | 1919 } |
1924 } | 1920 } |
1925 | 1921 |
1926 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 1922 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
1927 // ----------- S t a t e ------------- | 1923 // ----------- S t a t e ------------- |
1928 // -- r0 : argc | 1924 // -- r0 : argc |
1929 // -- sp[0] : new.target (optional) | 1925 // -- sp[0] : new.target (optional) |
1930 // -- sp[4] : argumentsList | 1926 // -- sp[4] : argumentsList |
1931 // -- sp[8] : target | 1927 // -- sp[8] : target |
1932 // -- sp[12] : receiver | 1928 // -- sp[12] : receiver |
1933 // ----------------------------------- | 1929 // ----------------------------------- |
1934 | 1930 |
1935 // 1. Load target into r1 (if present), argumentsList into r0 (if present), | 1931 // 1. Load target into r1 (if present), argumentsList into r2 (if present), |
1936 // new.target into r3 (if present, otherwise use target), remove all | 1932 // new.target into r3 (if present, otherwise use target), remove all |
1937 // arguments from the stack (including the receiver), and push thisArgument | 1933 // arguments from the stack (including the receiver), and push thisArgument |
1938 // (if present) instead. | 1934 // (if present) instead. |
1939 { | 1935 { |
1940 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); | 1936 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); |
1941 __ mov(r2, r1); | 1937 __ mov(r2, r1); |
1942 __ str(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // receiver | 1938 __ str(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // receiver |
1943 __ sub(r4, r0, Operand(1), SetCC); | 1939 __ sub(r4, r0, Operand(1), SetCC); |
1944 __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // target | 1940 __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // target |
1945 __ mov(r3, r1); // new.target defaults to target | 1941 __ mov(r3, r1); // new.target defaults to target |
1946 __ sub(r4, r4, Operand(1), SetCC, ge); | 1942 __ sub(r4, r4, Operand(1), SetCC, ge); |
1947 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argumentsList | 1943 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argumentsList |
1948 __ sub(r4, r4, Operand(1), SetCC, ge); | 1944 __ sub(r4, r4, Operand(1), SetCC, ge); |
1949 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // new.target | 1945 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // new.target |
1950 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); | 1946 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); |
1951 __ mov(r0, r2); | |
1952 } | 1947 } |
1953 | 1948 |
1954 // ----------- S t a t e ------------- | 1949 // ----------- S t a t e ------------- |
1955 // -- r0 : argumentsList | 1950 // -- r2 : argumentsList |
1956 // -- r3 : new.target | 1951 // -- r3 : new.target |
1957 // -- r1 : target | 1952 // -- r1 : target |
1958 // -- sp[0] : receiver (undefined) | 1953 // -- sp[0] : receiver (undefined) |
1959 // ----------------------------------- | 1954 // ----------------------------------- |
1960 | 1955 |
1961 // 2. Make sure the target is actually a constructor. | 1956 // 2. Make sure the target is actually a constructor. |
1962 Label target_not_constructor; | 1957 Label target_not_constructor; |
1963 __ JumpIfSmi(r1, &target_not_constructor); | 1958 __ JumpIfSmi(r1, &target_not_constructor); |
1964 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1959 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1965 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | 1960 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); |
1966 __ tst(r4, Operand(1 << Map::kIsConstructor)); | 1961 __ tst(r4, Operand(1 << Map::kIsConstructor)); |
1967 __ b(eq, &target_not_constructor); | 1962 __ b(eq, &target_not_constructor); |
1968 | 1963 |
1969 // 3. Make sure the target is actually a constructor. | 1964 // 3. Make sure the target is actually a constructor. |
1970 Label new_target_not_constructor; | 1965 Label new_target_not_constructor; |
1971 __ JumpIfSmi(r3, &new_target_not_constructor); | 1966 __ JumpIfSmi(r3, &new_target_not_constructor); |
1972 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); | 1967 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); |
1973 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | 1968 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); |
1974 __ tst(r4, Operand(1 << Map::kIsConstructor)); | 1969 __ tst(r4, Operand(1 << Map::kIsConstructor)); |
1975 __ b(eq, &new_target_not_constructor); | 1970 __ b(eq, &new_target_not_constructor); |
1976 | 1971 |
1977 // 4a. Construct the target with the given new.target and argumentsList. | 1972 // 4a. Construct the target with the given new.target and argumentsList. |
1978 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1973 __ Jump(masm->isolate()->builtins()->ConstructWithArrayLike(), |
| 1974 RelocInfo::CODE_TARGET); |
1979 | 1975 |
1980 // 4b. The target is not a constructor, throw an appropriate TypeError. | 1976 // 4b. The target is not a constructor, throw an appropriate TypeError. |
1981 __ bind(&target_not_constructor); | 1977 __ bind(&target_not_constructor); |
1982 { | 1978 { |
1983 __ str(r1, MemOperand(sp, 0)); | 1979 __ str(r1, MemOperand(sp, 0)); |
1984 __ TailCallRuntime(Runtime::kThrowNotConstructor); | 1980 __ TailCallRuntime(Runtime::kThrowNotConstructor); |
1985 } | 1981 } |
1986 | 1982 |
1987 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1983 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
1988 __ bind(&new_target_not_constructor); | 1984 __ bind(&new_target_not_constructor); |
(...skipping 20 matching lines...) Expand all Loading... |
2009 // then tear down the parameters. | 2005 // then tear down the parameters. |
2010 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 2006 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
2011 kPointerSize))); | 2007 kPointerSize))); |
2012 | 2008 |
2013 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); | 2009 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); |
2014 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); | 2010 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); |
2015 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver | 2011 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver |
2016 } | 2012 } |
2017 | 2013 |
2018 // static | 2014 // static |
2019 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2015 void Builtins::Generate_Varargs(MacroAssembler* masm, Handle<Code> code) { |
2020 // ----------- S t a t e ------------- | 2016 // ----------- S t a t e ------------- |
2021 // -- r0 : argumentsList | 2017 // -- r1 : target |
2022 // -- r1 : target | 2018 // -- r0 : number of parameters on the stack (not including the receiver) |
2023 // -- r3 : new.target (checked to be constructor or undefined) | 2019 // -- r2 : arguments list (a FixedArray) |
2024 // -- sp[0] : thisArgument | 2020 // -- r4 : len (number of elements to push from args) |
| 2021 // -- r3 : new.target (for [[Construct]]) |
2025 // ----------------------------------- | 2022 // ----------------------------------- |
2026 | 2023 __ AssertFixedArray(r2); |
2027 // Create the list of arguments from the array-like argumentsList. | |
2028 { | |
2029 Label create_arguments, create_array, create_holey_array, create_runtime, | |
2030 done_create; | |
2031 __ JumpIfSmi(r0, &create_runtime); | |
2032 | |
2033 // Load the map of argumentsList into r2. | |
2034 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); | |
2035 | |
2036 // Load native context into r4. | |
2037 __ ldr(r4, NativeContextMemOperand()); | |
2038 | |
2039 // Check if argumentsList is an (unmodified) arguments object. | |
2040 __ ldr(ip, ContextMemOperand(r4, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | |
2041 __ cmp(ip, r2); | |
2042 __ b(eq, &create_arguments); | |
2043 __ ldr(ip, ContextMemOperand(r4, Context::STRICT_ARGUMENTS_MAP_INDEX)); | |
2044 __ cmp(ip, r2); | |
2045 __ b(eq, &create_arguments); | |
2046 | |
2047 // Check if argumentsList is a fast JSArray. | |
2048 __ CompareInstanceType(r2, ip, JS_ARRAY_TYPE); | |
2049 __ b(eq, &create_array); | |
2050 | |
2051 // Ask the runtime to create the list (actually a FixedArray). | |
2052 __ bind(&create_runtime); | |
2053 { | |
2054 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
2055 __ Push(r1, r3, r0); | |
2056 __ CallRuntime(Runtime::kCreateListFromArrayLike); | |
2057 __ Pop(r1, r3); | |
2058 __ ldr(r2, FieldMemOperand(r0, FixedArray::kLengthOffset)); | |
2059 __ SmiUntag(r2); | |
2060 } | |
2061 __ jmp(&done_create); | |
2062 | |
2063 // Try to create the list from an arguments object. | |
2064 __ bind(&create_arguments); | |
2065 __ ldr(r2, FieldMemOperand(r0, JSArgumentsObject::kLengthOffset)); | |
2066 __ ldr(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); | |
2067 __ ldr(ip, FieldMemOperand(r4, FixedArray::kLengthOffset)); | |
2068 __ cmp(r2, ip); | |
2069 __ b(ne, &create_runtime); | |
2070 __ SmiUntag(r2); | |
2071 __ mov(r0, r4); | |
2072 __ b(&done_create); | |
2073 | |
2074 // For holey JSArrays we need to check that the array prototype chain | |
2075 // protector is intact and our prototype is the Array.prototype actually. | |
2076 __ bind(&create_holey_array); | |
2077 __ ldr(r2, FieldMemOperand(r2, Map::kPrototypeOffset)); | |
2078 __ ldr(r4, ContextMemOperand(r4, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); | |
2079 __ cmp(r2, r4); | |
2080 __ b(ne, &create_runtime); | |
2081 __ LoadRoot(r4, Heap::kArrayProtectorRootIndex); | |
2082 __ ldr(r2, FieldMemOperand(r4, PropertyCell::kValueOffset)); | |
2083 __ cmp(r2, Operand(Smi::FromInt(Isolate::kProtectorValid))); | |
2084 __ b(ne, &create_runtime); | |
2085 __ ldr(r2, FieldMemOperand(r0, JSArray::kLengthOffset)); | |
2086 __ ldr(r0, FieldMemOperand(r0, JSArray::kElementsOffset)); | |
2087 __ SmiUntag(r2); | |
2088 __ b(&done_create); | |
2089 | |
2090 // Try to create the list from a JSArray object. | |
2091 // -- r2 and r4 must be preserved till bne create_holey_array. | |
2092 __ bind(&create_array); | |
2093 __ ldr(r5, FieldMemOperand(r2, Map::kBitField2Offset)); | |
2094 __ DecodeField<Map::ElementsKindBits>(r5); | |
2095 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
2096 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
2097 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
2098 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
2099 __ cmp(r5, Operand(FAST_HOLEY_ELEMENTS)); | |
2100 __ b(hi, &create_runtime); | |
2101 // Only FAST_XXX after this point, FAST_HOLEY_XXX are odd values. | |
2102 __ tst(r5, Operand(1)); | |
2103 __ b(ne, &create_holey_array); | |
2104 // FAST_SMI_ELEMENTS or FAST_ELEMENTS after this point. | |
2105 __ ldr(r2, FieldMemOperand(r0, JSArray::kLengthOffset)); | |
2106 __ ldr(r0, FieldMemOperand(r0, JSArray::kElementsOffset)); | |
2107 __ SmiUntag(r2); | |
2108 | |
2109 __ bind(&done_create); | |
2110 } | |
2111 | 2024 |
2112 // Check for stack overflow. | 2025 // Check for stack overflow. |
2113 { | 2026 { |
2114 // Check the stack for overflow. We are not trying to catch interruptions | 2027 // Check the stack for overflow. We are not trying to catch interruptions |
2115 // (i.e. debug break and preemption) here, so check the "real stack limit". | 2028 // (i.e. debug break and preemption) here, so check the "real stack limit". |
2116 Label done; | 2029 Label done; |
2117 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex); | 2030 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex); |
2118 // Make ip the space we have left. The stack might already be overflowed | 2031 // Make ip the space we have left. The stack might already be overflowed |
2119 // here which will cause ip to become negative. | 2032 // here which will cause ip to become negative. |
2120 __ sub(ip, sp, ip); | 2033 __ sub(ip, sp, ip); |
2121 // Check if the arguments will overflow the stack. | 2034 // Check if the arguments will overflow the stack. |
2122 __ cmp(ip, Operand(r2, LSL, kPointerSizeLog2)); | 2035 __ cmp(ip, Operand(r4, LSL, kPointerSizeLog2)); |
2123 __ b(gt, &done); // Signed comparison. | 2036 __ b(gt, &done); // Signed comparison. |
2124 __ TailCallRuntime(Runtime::kThrowStackOverflow); | 2037 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
2125 __ bind(&done); | 2038 __ bind(&done); |
2126 } | 2039 } |
2127 | 2040 |
2128 // ----------- S t a t e ------------- | |
2129 // -- r1 : target | |
2130 // -- r0 : args (a FixedArray built from argumentsList) | |
2131 // -- r2 : len (number of elements to push from args) | |
2132 // -- r3 : new.target (checked to be constructor or undefined) | |
2133 // -- sp[0] : thisArgument | |
2134 // ----------------------------------- | |
2135 | |
2136 // Push arguments onto the stack (thisArgument is already on the stack). | 2041 // Push arguments onto the stack (thisArgument is already on the stack). |
2137 { | 2042 { |
2138 __ mov(r4, Operand(0)); | 2043 __ mov(r6, Operand(0)); |
2139 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); | 2044 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); |
2140 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); | |
2141 Label done, loop; | 2045 Label done, loop; |
2142 __ bind(&loop); | 2046 __ bind(&loop); |
2143 __ cmp(r4, r2); | 2047 __ cmp(r6, r4); |
2144 __ b(eq, &done); | 2048 __ b(eq, &done); |
2145 __ add(ip, r0, Operand(r4, LSL, kPointerSizeLog2)); | 2049 __ add(ip, r2, Operand(r6, LSL, kPointerSizeLog2)); |
2146 __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize)); | 2050 __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize)); |
2147 __ cmp(r5, ip); | 2051 __ cmp(ip, r5); |
2148 __ mov(ip, r6, LeaveCC, eq); | 2052 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex, eq); |
2149 __ Push(ip); | 2053 __ Push(ip); |
2150 __ add(r4, r4, Operand(1)); | 2054 __ add(r6, r6, Operand(1)); |
2151 __ b(&loop); | 2055 __ b(&loop); |
2152 __ bind(&done); | 2056 __ bind(&done); |
2153 __ Move(r0, r4); | 2057 __ add(r0, r0, r6); |
2154 } | 2058 } |
2155 | 2059 |
2156 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2060 // Tail-call to the actual Call or Construct builtin. |
2157 { | 2061 __ Jump(code, RelocInfo::CODE_TARGET); |
2158 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); | |
2159 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq); | |
2160 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | |
2161 } | |
2162 } | 2062 } |
2163 | 2063 |
2164 // static | 2064 // static |
2165 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, | 2065 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, |
2166 Handle<Code> code) { | 2066 Handle<Code> code) { |
2167 // ----------- S t a t e ------------- | 2067 // ----------- S t a t e ------------- |
2168 // -- r0 : the number of arguments (not including the receiver) | 2068 // -- r0 : the number of arguments (not including the receiver) |
2169 // -- r3 : the new.target (for [[Construct]] calls) | 2069 // -- r3 : the new.target (for [[Construct]] calls) |
2170 // -- r1 : the target to call (can be any Object) | 2070 // -- r1 : the target to call (can be any Object) |
2171 // -- r2 : start index (to support rest parameters) | 2071 // -- r2 : start index (to support rest parameters) |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3062 } | 2962 } |
3063 // Now jump to the instructions of the returned code object. | 2963 // Now jump to the instructions of the returned code object. |
3064 __ Jump(r8); | 2964 __ Jump(r8); |
3065 } | 2965 } |
3066 #undef __ | 2966 #undef __ |
3067 | 2967 |
3068 } // namespace internal | 2968 } // namespace internal |
3069 } // namespace v8 | 2969 } // namespace v8 |
3070 | 2970 |
3071 #endif // V8_TARGET_ARCH_ARM | 2971 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |