Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: src/builtins/arm/builtins-arm.cc

Issue 2930623002: [builtins] Start refactoring the Apply builtin. (Closed)
Patch Set: Address feedback. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/bailout-reason.h ('k') | src/builtins/arm64/builtins-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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_CallOrConstructVarargs(MacroAssembler* masm,
2016 Handle<Code> code) {
2020 // ----------- S t a t e ------------- 2017 // ----------- S t a t e -------------
2021 // -- r0 : argumentsList 2018 // -- r1 : target
2022 // -- r1 : target 2019 // -- r0 : number of parameters on the stack (not including the receiver)
2023 // -- r3 : new.target (checked to be constructor or undefined) 2020 // -- r2 : arguments list (a FixedArray)
2024 // -- sp[0] : thisArgument 2021 // -- r4 : len (number of elements to push from args)
2022 // -- r3 : new.target (for [[Construct]])
2025 // ----------------------------------- 2023 // -----------------------------------
2026 2024 __ 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 2025
2112 // Check for stack overflow. 2026 // Check for stack overflow.
2113 { 2027 {
2114 // Check the stack for overflow. We are not trying to catch interruptions 2028 // 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". 2029 // (i.e. debug break and preemption) here, so check the "real stack limit".
2116 Label done; 2030 Label done;
2117 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex); 2031 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex);
2118 // Make ip the space we have left. The stack might already be overflowed 2032 // Make ip the space we have left. The stack might already be overflowed
2119 // here which will cause ip to become negative. 2033 // here which will cause ip to become negative.
2120 __ sub(ip, sp, ip); 2034 __ sub(ip, sp, ip);
2121 // Check if the arguments will overflow the stack. 2035 // Check if the arguments will overflow the stack.
2122 __ cmp(ip, Operand(r2, LSL, kPointerSizeLog2)); 2036 __ cmp(ip, Operand(r4, LSL, kPointerSizeLog2));
2123 __ b(gt, &done); // Signed comparison. 2037 __ b(gt, &done); // Signed comparison.
2124 __ TailCallRuntime(Runtime::kThrowStackOverflow); 2038 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2125 __ bind(&done); 2039 __ bind(&done);
2126 } 2040 }
2127 2041
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). 2042 // Push arguments onto the stack (thisArgument is already on the stack).
2137 { 2043 {
2138 __ mov(r4, Operand(0)); 2044 __ mov(r6, Operand(0));
2139 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); 2045 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
2140 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
2141 Label done, loop; 2046 Label done, loop;
2142 __ bind(&loop); 2047 __ bind(&loop);
2143 __ cmp(r4, r2); 2048 __ cmp(r6, r4);
2144 __ b(eq, &done); 2049 __ b(eq, &done);
2145 __ add(ip, r0, Operand(r4, LSL, kPointerSizeLog2)); 2050 __ add(ip, r2, Operand(r6, LSL, kPointerSizeLog2));
2146 __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize)); 2051 __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize));
2147 __ cmp(r5, ip); 2052 __ cmp(ip, r5);
2148 __ mov(ip, r6, LeaveCC, eq); 2053 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex, eq);
2149 __ Push(ip); 2054 __ Push(ip);
2150 __ add(r4, r4, Operand(1)); 2055 __ add(r6, r6, Operand(1));
2151 __ b(&loop); 2056 __ b(&loop);
2152 __ bind(&done); 2057 __ bind(&done);
2153 __ Move(r0, r4); 2058 __ add(r0, r0, r6);
2154 } 2059 }
2155 2060
2156 // Dispatch to Call or Construct depending on whether new.target is undefined. 2061 // Tail-call to the actual Call or Construct builtin.
2157 { 2062 __ 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 } 2063 }
2163 2064
2164 // static 2065 // static
2165 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, 2066 void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
2166 Handle<Code> code) { 2067 Handle<Code> code) {
2167 // ----------- S t a t e ------------- 2068 // ----------- S t a t e -------------
2168 // -- r0 : the number of arguments (not including the receiver) 2069 // -- r0 : the number of arguments (not including the receiver)
2169 // -- r3 : the new.target (for [[Construct]] calls) 2070 // -- r3 : the new.target (for [[Construct]] calls)
2170 // -- r1 : the target to call (can be any Object) 2071 // -- r1 : the target to call (can be any Object)
2171 // -- r2 : start index (to support rest parameters) 2072 // -- r2 : start index (to support rest parameters)
2172 // ----------------------------------- 2073 // -----------------------------------
2173 2074
2174 // Check if we have an arguments adaptor frame below the function frame. 2075 // Check if we have an arguments adaptor frame below the function frame.
2175 Label arguments_adaptor, arguments_done; 2076 Label arguments_adaptor, arguments_done;
2176 __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 2077 __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
3062 } 2963 }
3063 // Now jump to the instructions of the returned code object. 2964 // Now jump to the instructions of the returned code object.
3064 __ Jump(r8); 2965 __ Jump(r8);
3065 } 2966 }
3066 #undef __ 2967 #undef __
3067 2968
3068 } // namespace internal 2969 } // namespace internal
3069 } // namespace v8 2970 } // namespace v8
3070 2971
3071 #endif // V8_TARGET_ARCH_ARM 2972 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/bailout-reason.h ('k') | src/builtins/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698