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

Side by Side Diff: src/builtins/mips64/builtins-mips64.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/builtins/mips/builtins-mips.cc ('k') | src/builtins/x64/builtins-x64.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_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 // static 1752 // static
1753 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { 1753 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1754 // ----------- S t a t e ------------- 1754 // ----------- S t a t e -------------
1755 // -- a0 : argc 1755 // -- a0 : argc
1756 // -- sp[0] : argArray 1756 // -- sp[0] : argArray
1757 // -- sp[4] : thisArg 1757 // -- sp[4] : thisArg
1758 // -- sp[8] : receiver 1758 // -- sp[8] : receiver
1759 // ----------------------------------- 1759 // -----------------------------------
1760 1760
1761 Register argc = a0; 1761 Register argc = a0;
1762 Register arg_array = a0; 1762 Register arg_array = a2;
1763 Register receiver = a1; 1763 Register receiver = a1;
1764 Register this_arg = a2; 1764 Register this_arg = a5;
1765 Register undefined_value = a3; 1765 Register undefined_value = a3;
1766 Register scratch = a4; 1766 Register scratch = a4;
1767 1767
1768 __ LoadRoot(undefined_value, Heap::kUndefinedValueRootIndex); 1768 __ LoadRoot(undefined_value, Heap::kUndefinedValueRootIndex);
1769 // 1. Load receiver into a1, argArray into a0 (if present), remove all 1769 // 1. Load receiver into a1, argArray into a2 (if present), remove all
1770 // arguments from the stack (including the receiver), and push thisArg (if 1770 // arguments from the stack (including the receiver), and push thisArg (if
1771 // present) instead. 1771 // present) instead.
1772 { 1772 {
1773 // Claim (2 - argc) dummy arguments form the stack, to put the stack in a 1773 // Claim (2 - argc) dummy arguments form the stack, to put the stack in a
1774 // consistent state for a simple pop operation. 1774 // consistent state for a simple pop operation.
1775 1775
1776 __ Dsubu(sp, sp, Operand(2 * kPointerSize)); 1776 __ Dsubu(sp, sp, Operand(2 * kPointerSize));
1777 __ Dlsa(sp, sp, argc, kPointerSizeLog2); 1777 __ Dlsa(sp, sp, argc, kPointerSizeLog2);
1778 __ mov(scratch, argc); 1778 __ mov(scratch, argc);
1779 __ Pop(this_arg, arg_array); // Overwrite argc 1779 __ Pop(this_arg, arg_array); // Overwrite argc
1780 __ Movz(arg_array, undefined_value, scratch); // if argc == 0 1780 __ Movz(arg_array, undefined_value, scratch); // if argc == 0
1781 __ Movz(this_arg, undefined_value, scratch); // if argc == 0 1781 __ Movz(this_arg, undefined_value, scratch); // if argc == 0
1782 __ Dsubu(scratch, scratch, Operand(1)); 1782 __ Dsubu(scratch, scratch, Operand(1));
1783 __ Movz(arg_array, undefined_value, scratch); // if argc == 1 1783 __ Movz(arg_array, undefined_value, scratch); // if argc == 1
1784 __ Ld(receiver, MemOperand(sp)); 1784 __ Ld(receiver, MemOperand(sp));
1785 __ Sd(this_arg, MemOperand(sp)); 1785 __ Sd(this_arg, MemOperand(sp));
1786 } 1786 }
1787 1787
1788 // ----------- S t a t e ------------- 1788 // ----------- S t a t e -------------
1789 // -- a0 : argArray 1789 // -- a2 : argArray
1790 // -- a1 : receiver 1790 // -- a1 : receiver
1791 // -- a3 : undefined root value 1791 // -- a3 : undefined root value
1792 // -- sp[0] : thisArg 1792 // -- sp[0] : thisArg
1793 // ----------------------------------- 1793 // -----------------------------------
1794 1794
1795 // 2. Make sure the receiver is actually callable. 1795 // 2. Make sure the receiver is actually callable.
1796 Label receiver_not_callable; 1796 Label receiver_not_callable;
1797 __ JumpIfSmi(receiver, &receiver_not_callable); 1797 __ JumpIfSmi(receiver, &receiver_not_callable);
1798 __ Ld(a4, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1798 __ Ld(a4, FieldMemOperand(receiver, HeapObject::kMapOffset));
1799 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset)); 1799 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1800 __ And(a4, a4, Operand(1 << Map::kIsCallable)); 1800 __ And(a4, a4, Operand(1 << Map::kIsCallable));
1801 __ Branch(&receiver_not_callable, eq, a4, Operand(zero_reg)); 1801 __ Branch(&receiver_not_callable, eq, a4, Operand(zero_reg));
1802 1802
1803 // 3. Tail call with no arguments if argArray is null or undefined. 1803 // 3. Tail call with no arguments if argArray is null or undefined.
1804 Label no_arguments; 1804 Label no_arguments;
1805 __ JumpIfRoot(arg_array, Heap::kNullValueRootIndex, &no_arguments); 1805 __ JumpIfRoot(arg_array, Heap::kNullValueRootIndex, &no_arguments);
1806 __ Branch(&no_arguments, eq, arg_array, Operand(undefined_value)); 1806 __ Branch(&no_arguments, eq, arg_array, Operand(undefined_value));
1807 1807
1808 // 4a. Apply the receiver to the given argArray (passing undefined for 1808 // 4a. Apply the receiver to the given argArray.
1809 // new.target). 1809 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(),
1810 DCHECK(undefined_value.is(a3)); 1810 RelocInfo::CODE_TARGET);
1811 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1812 1811
1813 // 4b. The argArray is either null or undefined, so we tail call without any 1812 // 4b. The argArray is either null or undefined, so we tail call without any
1814 // arguments to the receiver. 1813 // arguments to the receiver.
1815 __ bind(&no_arguments); 1814 __ bind(&no_arguments);
1816 { 1815 {
1817 __ mov(a0, zero_reg); 1816 __ mov(a0, zero_reg);
1818 DCHECK(receiver.is(a1)); 1817 DCHECK(receiver.is(a1));
1819 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 1818 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1820 } 1819 }
1821 1820
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { 1871 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1873 // ----------- S t a t e ------------- 1872 // ----------- S t a t e -------------
1874 // -- a0 : argc 1873 // -- a0 : argc
1875 // -- sp[0] : argumentsList (if argc ==3) 1874 // -- sp[0] : argumentsList (if argc ==3)
1876 // -- sp[4] : thisArgument (if argc >=2) 1875 // -- sp[4] : thisArgument (if argc >=2)
1877 // -- sp[8] : target (if argc >=1) 1876 // -- sp[8] : target (if argc >=1)
1878 // -- sp[12] : receiver 1877 // -- sp[12] : receiver
1879 // ----------------------------------- 1878 // -----------------------------------
1880 1879
1881 Register argc = a0; 1880 Register argc = a0;
1882 Register arguments_list = a0; 1881 Register arguments_list = a2;
1883 Register target = a1; 1882 Register target = a1;
1884 Register this_argument = a2; 1883 Register this_argument = a5;
1885 Register undefined_value = a3; 1884 Register undefined_value = a3;
1886 Register scratch = a4; 1885 Register scratch = a4;
1887 1886
1888 __ LoadRoot(undefined_value, Heap::kUndefinedValueRootIndex); 1887 __ LoadRoot(undefined_value, Heap::kUndefinedValueRootIndex);
1889 // 1. Load target into a1 (if present), argumentsList into a0 (if present), 1888 // 1. Load target into a1 (if present), argumentsList into a2 (if present),
1890 // remove all arguments from the stack (including the receiver), and push 1889 // remove all arguments from the stack (including the receiver), and push
1891 // thisArgument (if present) instead. 1890 // thisArgument (if present) instead.
1892 { 1891 {
1893 // Claim (3 - argc) dummy arguments form the stack, to put the stack in a 1892 // Claim (3 - argc) dummy arguments form the stack, to put the stack in a
1894 // consistent state for a simple pop operation. 1893 // consistent state for a simple pop operation.
1895 1894
1896 __ Dsubu(sp, sp, Operand(3 * kPointerSize)); 1895 __ Dsubu(sp, sp, Operand(3 * kPointerSize));
1897 __ Dlsa(sp, sp, argc, kPointerSizeLog2); 1896 __ Dlsa(sp, sp, argc, kPointerSizeLog2);
1898 __ mov(scratch, argc); 1897 __ mov(scratch, argc);
1899 __ Pop(target, this_argument, arguments_list); 1898 __ Pop(target, this_argument, arguments_list);
1900 __ Movz(arguments_list, undefined_value, scratch); // if argc == 0 1899 __ Movz(arguments_list, undefined_value, scratch); // if argc == 0
1901 __ Movz(this_argument, undefined_value, scratch); // if argc == 0 1900 __ Movz(this_argument, undefined_value, scratch); // if argc == 0
1902 __ Movz(target, undefined_value, scratch); // if argc == 0 1901 __ Movz(target, undefined_value, scratch); // if argc == 0
1903 __ Dsubu(scratch, scratch, Operand(1)); 1902 __ Dsubu(scratch, scratch, Operand(1));
1904 __ Movz(arguments_list, undefined_value, scratch); // if argc == 1 1903 __ Movz(arguments_list, undefined_value, scratch); // if argc == 1
1905 __ Movz(this_argument, undefined_value, scratch); // if argc == 1 1904 __ Movz(this_argument, undefined_value, scratch); // if argc == 1
1906 __ Dsubu(scratch, scratch, Operand(1)); 1905 __ Dsubu(scratch, scratch, Operand(1));
1907 __ Movz(arguments_list, undefined_value, scratch); // if argc == 2 1906 __ Movz(arguments_list, undefined_value, scratch); // if argc == 2
1908 1907
1909 __ Sd(this_argument, MemOperand(sp, 0)); // Overwrite receiver 1908 __ Sd(this_argument, MemOperand(sp, 0)); // Overwrite receiver
1910 } 1909 }
1911 1910
1912 // ----------- S t a t e ------------- 1911 // ----------- S t a t e -------------
1913 // -- a0 : argumentsList 1912 // -- a2 : argumentsList
1914 // -- a1 : target 1913 // -- a1 : target
1915 // -- a3 : undefined root value 1914 // -- a3 : undefined root value
1916 // -- sp[0] : thisArgument 1915 // -- sp[0] : thisArgument
1917 // ----------------------------------- 1916 // -----------------------------------
1918 1917
1919 // 2. Make sure the target is actually callable. 1918 // 2. Make sure the target is actually callable.
1920 Label target_not_callable; 1919 Label target_not_callable;
1921 __ JumpIfSmi(target, &target_not_callable); 1920 __ JumpIfSmi(target, &target_not_callable);
1922 __ Ld(a4, FieldMemOperand(target, HeapObject::kMapOffset)); 1921 __ Ld(a4, FieldMemOperand(target, HeapObject::kMapOffset));
1923 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset)); 1922 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1924 __ And(a4, a4, Operand(1 << Map::kIsCallable)); 1923 __ And(a4, a4, Operand(1 << Map::kIsCallable));
1925 __ Branch(&target_not_callable, eq, a4, Operand(zero_reg)); 1924 __ Branch(&target_not_callable, eq, a4, Operand(zero_reg));
1926 1925
1927 // 3a. Apply the target to the given argumentsList (passing undefined for 1926 // 3a. Apply the target to the given argumentsList.
1928 // new.target). 1927 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(),
1929 DCHECK(undefined_value.is(a3)); 1928 RelocInfo::CODE_TARGET);
1930 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1931 1929
1932 // 3b. The target is not callable, throw an appropriate TypeError. 1930 // 3b. The target is not callable, throw an appropriate TypeError.
1933 __ bind(&target_not_callable); 1931 __ bind(&target_not_callable);
1934 { 1932 {
1935 __ Sd(target, MemOperand(sp)); 1933 __ Sd(target, MemOperand(sp));
1936 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); 1934 __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1937 } 1935 }
1938 } 1936 }
1939 1937
1940 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { 1938 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1941 // ----------- S t a t e ------------- 1939 // ----------- S t a t e -------------
1942 // -- a0 : argc 1940 // -- a0 : argc
1943 // -- sp[0] : new.target (optional) (dummy value if argc <= 2) 1941 // -- sp[0] : new.target (optional) (dummy value if argc <= 2)
1944 // -- sp[4] : argumentsList (dummy value if argc <= 1) 1942 // -- sp[4] : argumentsList (dummy value if argc <= 1)
1945 // -- sp[8] : target (dummy value if argc == 0) 1943 // -- sp[8] : target (dummy value if argc == 0)
1946 // -- sp[12] : receiver 1944 // -- sp[12] : receiver
1947 // ----------------------------------- 1945 // -----------------------------------
1948 Register argc = a0; 1946 Register argc = a0;
1949 Register arguments_list = a0; 1947 Register arguments_list = a2;
1950 Register target = a1; 1948 Register target = a1;
1951 Register new_target = a3; 1949 Register new_target = a3;
1952 Register undefined_value = a4; 1950 Register undefined_value = a4;
1953 Register scratch = a5; 1951 Register scratch = a5;
1954 1952
1955 // 1. Load target into a1 (if present), argumentsList into a0 (if present), 1953 // 1. Load target into a1 (if present), argumentsList into a2 (if present),
1956 // new.target into a3 (if present, otherwise use target), remove all 1954 // new.target into a3 (if present, otherwise use target), remove all
1957 // arguments from the stack (including the receiver), and push thisArgument 1955 // arguments from the stack (including the receiver), and push thisArgument
1958 // (if present) instead. 1956 // (if present) instead.
1959 { 1957 {
1960 // Claim (3 - argc) dummy arguments form the stack, to put the stack in a 1958 // Claim (3 - argc) dummy arguments form the stack, to put the stack in a
1961 // consistent state for a simple pop operation. 1959 // consistent state for a simple pop operation.
1962 1960
1963 __ Dsubu(sp, sp, Operand(3 * kPointerSize)); 1961 __ Dsubu(sp, sp, Operand(3 * kPointerSize));
1964 __ Dlsa(sp, sp, argc, kPointerSizeLog2); 1962 __ Dlsa(sp, sp, argc, kPointerSizeLog2);
1965 __ mov(scratch, argc); 1963 __ mov(scratch, argc);
1966 __ Pop(target, arguments_list, new_target); 1964 __ Pop(target, arguments_list, new_target);
1967 __ Movz(arguments_list, undefined_value, scratch); // if argc == 0 1965 __ Movz(arguments_list, undefined_value, scratch); // if argc == 0
1968 __ Movz(new_target, undefined_value, scratch); // if argc == 0 1966 __ Movz(new_target, undefined_value, scratch); // if argc == 0
1969 __ Movz(target, undefined_value, scratch); // if argc == 0 1967 __ Movz(target, undefined_value, scratch); // if argc == 0
1970 __ Dsubu(scratch, scratch, Operand(1)); 1968 __ Dsubu(scratch, scratch, Operand(1));
1971 __ Movz(arguments_list, undefined_value, scratch); // if argc == 1 1969 __ Movz(arguments_list, undefined_value, scratch); // if argc == 1
1972 __ Movz(new_target, target, scratch); // if argc == 1 1970 __ Movz(new_target, target, scratch); // if argc == 1
1973 __ Dsubu(scratch, scratch, Operand(1)); 1971 __ Dsubu(scratch, scratch, Operand(1));
1974 __ Movz(new_target, target, scratch); // if argc == 2 1972 __ Movz(new_target, target, scratch); // if argc == 2
1975 1973
1976 __ Sd(undefined_value, MemOperand(sp, 0)); // Overwrite receiver 1974 __ Sd(undefined_value, MemOperand(sp, 0)); // Overwrite receiver
1977 } 1975 }
1978 1976
1979 // ----------- S t a t e ------------- 1977 // ----------- S t a t e -------------
1980 // -- a0 : argumentsList 1978 // -- a2 : argumentsList
1981 // -- a1 : target 1979 // -- a1 : target
1982 // -- a3 : new.target 1980 // -- a3 : new.target
1983 // -- sp[0] : receiver (undefined) 1981 // -- sp[0] : receiver (undefined)
1984 // ----------------------------------- 1982 // -----------------------------------
1985 1983
1986 // 2. Make sure the target is actually a constructor. 1984 // 2. Make sure the target is actually a constructor.
1987 Label target_not_constructor; 1985 Label target_not_constructor;
1988 __ JumpIfSmi(target, &target_not_constructor); 1986 __ JumpIfSmi(target, &target_not_constructor);
1989 __ Ld(a4, FieldMemOperand(target, HeapObject::kMapOffset)); 1987 __ Ld(a4, FieldMemOperand(target, HeapObject::kMapOffset));
1990 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset)); 1988 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1991 __ And(a4, a4, Operand(1 << Map::kIsConstructor)); 1989 __ And(a4, a4, Operand(1 << Map::kIsConstructor));
1992 __ Branch(&target_not_constructor, eq, a4, Operand(zero_reg)); 1990 __ Branch(&target_not_constructor, eq, a4, Operand(zero_reg));
1993 1991
1994 // 3. Make sure the target is actually a constructor. 1992 // 3. Make sure the target is actually a constructor.
1995 Label new_target_not_constructor; 1993 Label new_target_not_constructor;
1996 __ JumpIfSmi(new_target, &new_target_not_constructor); 1994 __ JumpIfSmi(new_target, &new_target_not_constructor);
1997 __ Ld(a4, FieldMemOperand(new_target, HeapObject::kMapOffset)); 1995 __ Ld(a4, FieldMemOperand(new_target, HeapObject::kMapOffset));
1998 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset)); 1996 __ Lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1999 __ And(a4, a4, Operand(1 << Map::kIsConstructor)); 1997 __ And(a4, a4, Operand(1 << Map::kIsConstructor));
2000 __ Branch(&new_target_not_constructor, eq, a4, Operand(zero_reg)); 1998 __ Branch(&new_target_not_constructor, eq, a4, Operand(zero_reg));
2001 1999
2002 // 4a. Construct the target with the given new.target and argumentsList. 2000 // 4a. Construct the target with the given new.target and argumentsList.
2003 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); 2001 __ Jump(masm->isolate()->builtins()->ConstructWithArrayLike(),
2002 RelocInfo::CODE_TARGET);
2004 2003
2005 // 4b. The target is not a constructor, throw an appropriate TypeError. 2004 // 4b. The target is not a constructor, throw an appropriate TypeError.
2006 __ bind(&target_not_constructor); 2005 __ bind(&target_not_constructor);
2007 { 2006 {
2008 __ Sd(target, MemOperand(sp)); 2007 __ Sd(target, MemOperand(sp));
2009 __ TailCallRuntime(Runtime::kThrowNotConstructor); 2008 __ TailCallRuntime(Runtime::kThrowNotConstructor);
2010 } 2009 }
2011 2010
2012 // 4c. The new.target is not a constructor, throw an appropriate TypeError. 2011 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2013 __ bind(&new_target_not_constructor); 2012 __ bind(&new_target_not_constructor);
(...skipping 22 matching lines...) Expand all
2036 kPointerSize))); 2035 kPointerSize)));
2037 __ mov(sp, fp); 2036 __ mov(sp, fp);
2038 __ MultiPop(fp.bit() | ra.bit()); 2037 __ MultiPop(fp.bit() | ra.bit());
2039 __ SmiScale(a4, a1, kPointerSizeLog2); 2038 __ SmiScale(a4, a1, kPointerSizeLog2);
2040 __ Daddu(sp, sp, a4); 2039 __ Daddu(sp, sp, a4);
2041 // Adjust for the receiver. 2040 // Adjust for the receiver.
2042 __ Daddu(sp, sp, Operand(kPointerSize)); 2041 __ Daddu(sp, sp, Operand(kPointerSize));
2043 } 2042 }
2044 2043
2045 // static 2044 // static
2046 void Builtins::Generate_Apply(MacroAssembler* masm) { 2045 void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
2046 Handle<Code> code) {
2047 // ----------- S t a t e ------------- 2047 // ----------- S t a t e -------------
2048 // -- a0 : argumentsList 2048 // -- a1 : target
2049 // -- a1 : target 2049 // -- a0 : number of parameters on the stack (not including the receiver)
2050 // -- a3 : new.target (checked to be constructor or undefined) 2050 // -- a2 : arguments list (a FixedArray)
2051 // -- sp[0] : thisArgument 2051 // -- a4 : len (number of elements to push from args)
2052 // -- a3 : new.target (for [[Construct]])
2052 // ----------------------------------- 2053 // -----------------------------------
2054 __ AssertFixedArray(a2);
2053 2055
2054 Register arguments_list = a0; 2056 Register args = a2;
2055 Register target = a1; 2057 Register len = a4;
2056 Register new_target = a3;
2057
2058 Register args = a0;
2059 Register len = a2;
2060
2061 // Create the list of arguments from the array-like argumentsList.
2062 {
2063 Label create_arguments, create_array, create_holey_array, create_runtime,
2064 done_create;
2065 __ JumpIfSmi(arguments_list, &create_runtime);
2066
2067 // Load the map of argumentsList into a2.
2068 Register arguments_list_map = a2;
2069 __ Ld(arguments_list_map,
2070 FieldMemOperand(arguments_list, HeapObject::kMapOffset));
2071
2072 // Load native context into a4.
2073 Register native_context = a4;
2074 __ Ld(native_context, NativeContextMemOperand());
2075
2076 // Check if argumentsList is an (unmodified) arguments object.
2077 __ Ld(at, ContextMemOperand(native_context,
2078 Context::SLOPPY_ARGUMENTS_MAP_INDEX));
2079 __ Branch(&create_arguments, eq, arguments_list_map, Operand(at));
2080 __ Ld(at, ContextMemOperand(native_context,
2081 Context::STRICT_ARGUMENTS_MAP_INDEX));
2082 __ Branch(&create_arguments, eq, arguments_list_map, Operand(at));
2083
2084 // Check if argumentsList is a fast JSArray.
2085 __ Lbu(v0, FieldMemOperand(a2, Map::kInstanceTypeOffset));
2086 __ Branch(&create_array, eq, v0, Operand(JS_ARRAY_TYPE));
2087
2088 // Ask the runtime to create the list (actually a FixedArray).
2089 __ bind(&create_runtime);
2090 {
2091 FrameScope scope(masm, StackFrame::INTERNAL);
2092 __ Push(target, new_target, arguments_list);
2093 __ CallRuntime(Runtime::kCreateListFromArrayLike);
2094 __ mov(arguments_list, v0);
2095 __ Pop(target, new_target);
2096 __ Lw(len, UntagSmiFieldMemOperand(v0, FixedArray::kLengthOffset));
2097 }
2098 __ Branch(&done_create);
2099
2100 // Try to create the list from an arguments object.
2101 __ bind(&create_arguments);
2102 __ Lw(len, UntagSmiFieldMemOperand(arguments_list,
2103 JSArgumentsObject::kLengthOffset));
2104 __ Ld(a4, FieldMemOperand(arguments_list, JSObject::kElementsOffset));
2105 __ Lw(at, UntagSmiFieldMemOperand(a4, FixedArray::kLengthOffset));
2106 __ Branch(&create_runtime, ne, len, Operand(at));
2107 __ mov(args, a4);
2108
2109 __ Branch(&done_create);
2110
2111 // For holey JSArrays we need to check that the array prototype chain
2112 // protector is intact and our prototype is the Array.prototype actually.
2113 __ bind(&create_holey_array);
2114 __ Ld(a2, FieldMemOperand(a2, Map::kPrototypeOffset));
2115 __ Ld(at, ContextMemOperand(native_context,
2116 Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2117 __ Branch(&create_runtime, ne, a2, Operand(at));
2118 __ LoadRoot(at, Heap::kArrayProtectorRootIndex);
2119 __ Lw(a2, FieldMemOperand(at, PropertyCell::kValueOffset));
2120 __ Branch(&create_runtime, ne, a2,
2121 Operand(Smi::FromInt(Isolate::kProtectorValid)));
2122 __ Lw(a2, UntagSmiFieldMemOperand(a0, JSArray::kLengthOffset));
2123 __ Ld(a0, FieldMemOperand(a0, JSArray::kElementsOffset));
2124 __ Branch(&done_create);
2125
2126 // Try to create the list from a JSArray object.
2127 __ bind(&create_array);
2128 __ Lbu(t1, FieldMemOperand(a2, Map::kBitField2Offset));
2129 __ DecodeField<Map::ElementsKindBits>(t1);
2130 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2131 STATIC_ASSERT(FAST_ELEMENTS == 2);
2132 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
2133 __ Branch(&create_holey_array, eq, t1, Operand(FAST_HOLEY_SMI_ELEMENTS));
2134 __ Branch(&create_holey_array, eq, t1, Operand(FAST_HOLEY_ELEMENTS));
2135 __ Branch(&create_runtime, hi, t1, Operand(FAST_ELEMENTS));
2136 __ Lw(a2, UntagSmiFieldMemOperand(arguments_list, JSArray::kLengthOffset));
2137 __ Ld(a0, FieldMemOperand(arguments_list, JSArray::kElementsOffset));
2138
2139 __ bind(&done_create);
2140 }
2141 2058
2142 // Check for stack overflow. 2059 // Check for stack overflow.
2143 { 2060 {
2144 // Check the stack for overflow. We are not trying to catch interruptions 2061 // Check the stack for overflow. We are not trying to catch interruptions
2145 // (i.e. debug break and preemption) here, so check the "real stack limit". 2062 // (i.e. debug break and preemption) here, so check the "real stack limit".
2146 Label done; 2063 Label done;
2147 __ LoadRoot(a4, Heap::kRealStackLimitRootIndex); 2064 __ LoadRoot(a5, Heap::kRealStackLimitRootIndex);
2148 // Make ip the space we have left. The stack might already be overflowed 2065 // Make ip the space we have left. The stack might already be overflowed
2149 // here which will cause ip to become negative. 2066 // here which will cause ip to become negative.
2150 __ Dsubu(a4, sp, a4); 2067 __ Dsubu(a5, sp, a5);
2151 // Check if the arguments will overflow the stack. 2068 // Check if the arguments will overflow the stack.
2152 __ dsll(at, len, kPointerSizeLog2); 2069 __ dsll(at, len, kPointerSizeLog2);
2153 __ Branch(&done, gt, a4, Operand(at)); // Signed comparison. 2070 __ Branch(&done, gt, a5, Operand(at)); // Signed comparison.
2154 __ TailCallRuntime(Runtime::kThrowStackOverflow); 2071 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2155 __ bind(&done); 2072 __ bind(&done);
2156 } 2073 }
2157 2074
2158 // ----------- S t a t e -------------
2159 // -- a1 : target
2160 // -- a0 : args (a FixedArray built from argumentsList)
2161 // -- a2 : len (number of elements to push from args)
2162 // -- a3 : new.target (checked to be constructor or undefined)
2163 // -- sp[0] : thisArgument
2164 // -----------------------------------
2165
2166 // Push arguments onto the stack (thisArgument is already on the stack). 2075 // Push arguments onto the stack (thisArgument is already on the stack).
2167 { 2076 {
2168 Label done, push, loop; 2077 Label done, push, loop;
2169 Register src = a4; 2078 Register src = a6;
2170 Register scratch = len; 2079 Register scratch = len;
2171 2080
2172 __ daddiu(src, args, FixedArray::kHeaderSize - kHeapObjectTag); 2081 __ daddiu(src, args, FixedArray::kHeaderSize - kHeapObjectTag);
2173 __ Branch(&done, eq, len, Operand(zero_reg), i::USE_DELAY_SLOT); 2082 __ Branch(&done, eq, len, Operand(zero_reg), i::USE_DELAY_SLOT);
2174 __ mov(a0, len); // The 'len' argument for Call() or Construct(). 2083 __ Daddu(a0, a0, len); // The 'len' argument for Call() or Construct().
2175 __ dsll(scratch, len, kPointerSizeLog2); 2084 __ dsll(scratch, len, kPointerSizeLog2);
2176 __ Dsubu(scratch, sp, Operand(scratch)); 2085 __ Dsubu(scratch, sp, Operand(scratch));
2177 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); 2086 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
2178 __ bind(&loop); 2087 __ bind(&loop);
2179 __ Ld(a5, MemOperand(src)); 2088 __ Ld(a5, MemOperand(src));
2180 __ Branch(&push, ne, a5, Operand(t1)); 2089 __ Branch(&push, ne, a5, Operand(t1));
2181 __ LoadRoot(a5, Heap::kUndefinedValueRootIndex); 2090 __ LoadRoot(a5, Heap::kUndefinedValueRootIndex);
2182 __ bind(&push); 2091 __ bind(&push);
2183 __ daddiu(src, src, kPointerSize); 2092 __ daddiu(src, src, kPointerSize);
2184 __ Push(a5); 2093 __ Push(a5);
2185 __ Branch(&loop, ne, scratch, Operand(sp)); 2094 __ Branch(&loop, ne, scratch, Operand(sp));
2186 __ bind(&done); 2095 __ bind(&done);
2187 } 2096 }
2188 2097
2189 // ----------- S t a t e ------------- 2098 // Tail-call to the actual Call or Construct builtin.
2190 // -- a0 : argument count (len) 2099 __ Jump(code, RelocInfo::CODE_TARGET);
2191 // -- a1 : target
2192 // -- a3 : new.target (checked to be constructor or undefinded)
2193 // -- sp[0] : args[len-1]
2194 // -- sp[8] : args[len-2]
2195 // ... : ...
2196 // -- sp[8*(len-2)] : args[1]
2197 // -- sp[8*(len-1)] : args[0]
2198 // ----------------------------------
2199
2200 // Dispatch to Call or Construct depending on whether new.target is undefined.
2201 {
2202 Label construct;
2203 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2204 __ Branch(&construct, ne, a3, Operand(at));
2205 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2206 __ bind(&construct);
2207 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2208 }
2209 } 2100 }
2210 2101
2211 // static 2102 // static
2212 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, 2103 void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
2213 Handle<Code> code) { 2104 Handle<Code> code) {
2214 // ----------- S t a t e ------------- 2105 // ----------- S t a t e -------------
2215 // -- a0 : the number of arguments (not including the receiver) 2106 // -- a0 : the number of arguments (not including the receiver)
2216 // -- a3 : the new.target (for [[Construct]] calls) 2107 // -- a3 : the new.target (for [[Construct]] calls)
2217 // -- a1 : the target to call (can be any Object) 2108 // -- a1 : the target to call (can be any Object)
2218 // -- a2 : start index (to support rest parameters) 2109 // -- a2 : start index (to support rest parameters)
2219 // ----------------------------------- 2110 // -----------------------------------
2220 2111
2221 // Check if we have an arguments adaptor frame below the function frame. 2112 // Check if we have an arguments adaptor frame below the function frame.
2222 Label arguments_adaptor, arguments_done; 2113 Label arguments_adaptor, arguments_done;
2223 __ Ld(a6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 2114 __ Ld(a6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
3151 __ Daddu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); 3042 __ Daddu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
3152 __ Jump(at); 3043 __ Jump(at);
3153 } 3044 }
3154 3045
3155 #undef __ 3046 #undef __
3156 3047
3157 } // namespace internal 3048 } // namespace internal
3158 } // namespace v8 3049 } // namespace v8
3159 3050
3160 #endif // V8_TARGET_ARCH_MIPS64 3051 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/builtins/mips/builtins-mips.cc ('k') | src/builtins/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698