OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_S390 | 5 #if V8_TARGET_ARCH_S390 |
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 1868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1879 | 1879 |
1880 // static | 1880 // static |
1881 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { | 1881 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { |
1882 // ----------- S t a t e ------------- | 1882 // ----------- S t a t e ------------- |
1883 // -- r2 : argc | 1883 // -- r2 : argc |
1884 // -- sp[0] : argArray | 1884 // -- sp[0] : argArray |
1885 // -- sp[4] : thisArg | 1885 // -- sp[4] : thisArg |
1886 // -- sp[8] : receiver | 1886 // -- sp[8] : receiver |
1887 // ----------------------------------- | 1887 // ----------------------------------- |
1888 | 1888 |
1889 // 1. Load receiver into r3, argArray into r2 (if present), remove all | 1889 // 1. Load receiver into r3, argArray into r4 (if present), remove all |
1890 // arguments from the stack (including the receiver), and push thisArg (if | 1890 // arguments from the stack (including the receiver), and push thisArg (if |
1891 // present) instead. | 1891 // present) instead. |
1892 { | 1892 { |
1893 Label skip; | 1893 Label skip; |
1894 Register arg_size = r4; | 1894 Register arg_size = r7; |
1895 Register new_sp = r5; | 1895 Register new_sp = r5; |
1896 Register scratch = r6; | 1896 Register scratch = r6; |
1897 __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); | 1897 __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); |
1898 __ AddP(new_sp, sp, arg_size); | 1898 __ AddP(new_sp, sp, arg_size); |
1899 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 1899 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
1900 __ LoadRR(scratch, r2); | 1900 __ LoadRR(r4, scratch); |
1901 __ LoadP(r3, MemOperand(new_sp, 0)); // receiver | 1901 __ LoadP(r3, MemOperand(new_sp, 0)); // receiver |
1902 __ CmpP(arg_size, Operand(kPointerSize)); | 1902 __ CmpP(arg_size, Operand(kPointerSize)); |
1903 __ blt(&skip); | 1903 __ blt(&skip); |
1904 __ LoadP(scratch, MemOperand(new_sp, 1 * -kPointerSize)); // thisArg | 1904 __ LoadP(scratch, MemOperand(new_sp, 1 * -kPointerSize)); // thisArg |
1905 __ beq(&skip); | 1905 __ beq(&skip); |
1906 __ LoadP(r2, MemOperand(new_sp, 2 * -kPointerSize)); // argArray | 1906 __ LoadP(r4, MemOperand(new_sp, 2 * -kPointerSize)); // argArray |
1907 __ bind(&skip); | 1907 __ bind(&skip); |
1908 __ LoadRR(sp, new_sp); | 1908 __ LoadRR(sp, new_sp); |
1909 __ StoreP(scratch, MemOperand(sp, 0)); | 1909 __ StoreP(scratch, MemOperand(sp, 0)); |
1910 } | 1910 } |
1911 | 1911 |
1912 // ----------- S t a t e ------------- | 1912 // ----------- S t a t e ------------- |
1913 // -- r2 : argArray | 1913 // -- r4 : argArray |
1914 // -- r3 : receiver | 1914 // -- r3 : receiver |
1915 // -- sp[0] : thisArg | 1915 // -- sp[0] : thisArg |
1916 // ----------------------------------- | 1916 // ----------------------------------- |
1917 | 1917 |
1918 // 2. Make sure the receiver is actually callable. | 1918 // 2. Make sure the receiver is actually callable. |
1919 Label receiver_not_callable; | 1919 Label receiver_not_callable; |
1920 __ JumpIfSmi(r3, &receiver_not_callable); | 1920 __ JumpIfSmi(r3, &receiver_not_callable); |
1921 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); | 1921 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); |
1922 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); | 1922 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); |
1923 __ TestBit(r6, Map::kIsCallable); | 1923 __ TestBit(r6, Map::kIsCallable); |
1924 __ beq(&receiver_not_callable); | 1924 __ beq(&receiver_not_callable); |
1925 | 1925 |
1926 // 3. Tail call with no arguments if argArray is null or undefined. | 1926 // 3. Tail call with no arguments if argArray is null or undefined. |
1927 Label no_arguments; | 1927 Label no_arguments; |
1928 __ JumpIfRoot(r2, Heap::kNullValueRootIndex, &no_arguments); | 1928 __ JumpIfRoot(r4, Heap::kNullValueRootIndex, &no_arguments); |
1929 __ JumpIfRoot(r2, Heap::kUndefinedValueRootIndex, &no_arguments); | 1929 __ JumpIfRoot(r4, Heap::kUndefinedValueRootIndex, &no_arguments); |
1930 | 1930 |
1931 // 4a. Apply the receiver to the given argArray (passing undefined for | 1931 // 4a. Apply the receiver to the given argArray. |
1932 // new.target). | 1932 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(), |
1933 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 1933 RelocInfo::CODE_TARGET); |
1934 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | |
1935 | 1934 |
1936 // 4b. The argArray is either null or undefined, so we tail call without any | 1935 // 4b. The argArray is either null or undefined, so we tail call without any |
1937 // arguments to the receiver. | 1936 // arguments to the receiver. |
1938 __ bind(&no_arguments); | 1937 __ bind(&no_arguments); |
1939 { | 1938 { |
1940 __ LoadImmP(r2, Operand::Zero()); | 1939 __ LoadImmP(r2, Operand::Zero()); |
1941 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1940 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1942 } | 1941 } |
1943 | 1942 |
1944 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1943 // 4c. The receiver is not callable, throw an appropriate TypeError. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1995 | 1994 |
1996 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1995 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
1997 // ----------- S t a t e ------------- | 1996 // ----------- S t a t e ------------- |
1998 // -- r2 : argc | 1997 // -- r2 : argc |
1999 // -- sp[0] : argumentsList | 1998 // -- sp[0] : argumentsList |
2000 // -- sp[4] : thisArgument | 1999 // -- sp[4] : thisArgument |
2001 // -- sp[8] : target | 2000 // -- sp[8] : target |
2002 // -- sp[12] : receiver | 2001 // -- sp[12] : receiver |
2003 // ----------------------------------- | 2002 // ----------------------------------- |
2004 | 2003 |
2005 // 1. Load target into r3 (if present), argumentsList into r2 (if present), | 2004 // 1. Load target into r3 (if present), argumentsList into r4 (if present), |
2006 // remove all arguments from the stack (including the receiver), and push | 2005 // remove all arguments from the stack (including the receiver), and push |
2007 // thisArgument (if present) instead. | 2006 // thisArgument (if present) instead. |
2008 { | 2007 { |
2009 Label skip; | 2008 Label skip; |
2010 Register arg_size = r4; | 2009 Register arg_size = r7; |
2011 Register new_sp = r5; | 2010 Register new_sp = r5; |
2012 Register scratch = r6; | 2011 Register scratch = r6; |
2013 __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); | 2012 __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); |
2014 __ AddP(new_sp, sp, arg_size); | 2013 __ AddP(new_sp, sp, arg_size); |
2015 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 2014 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
2016 __ LoadRR(scratch, r3); | 2015 __ LoadRR(scratch, r3); |
2017 __ LoadRR(r2, r3); | 2016 __ LoadRR(r4, r3); |
2018 __ CmpP(arg_size, Operand(kPointerSize)); | 2017 __ CmpP(arg_size, Operand(kPointerSize)); |
2019 __ blt(&skip); | 2018 __ blt(&skip); |
2020 __ LoadP(r3, MemOperand(new_sp, 1 * -kPointerSize)); // target | 2019 __ LoadP(r3, MemOperand(new_sp, 1 * -kPointerSize)); // target |
2021 __ beq(&skip); | 2020 __ beq(&skip); |
2022 __ LoadP(scratch, MemOperand(new_sp, 2 * -kPointerSize)); // thisArgument | 2021 __ LoadP(scratch, MemOperand(new_sp, 2 * -kPointerSize)); // thisArgument |
2023 __ CmpP(arg_size, Operand(2 * kPointerSize)); | 2022 __ CmpP(arg_size, Operand(2 * kPointerSize)); |
2024 __ beq(&skip); | 2023 __ beq(&skip); |
2025 __ LoadP(r2, MemOperand(new_sp, 3 * -kPointerSize)); // argumentsList | 2024 __ LoadP(r4, MemOperand(new_sp, 3 * -kPointerSize)); // argumentsList |
2026 __ bind(&skip); | 2025 __ bind(&skip); |
2027 __ LoadRR(sp, new_sp); | 2026 __ LoadRR(sp, new_sp); |
2028 __ StoreP(scratch, MemOperand(sp, 0)); | 2027 __ StoreP(scratch, MemOperand(sp, 0)); |
2029 } | 2028 } |
2030 | 2029 |
2031 // ----------- S t a t e ------------- | 2030 // ----------- S t a t e ------------- |
2032 // -- r2 : argumentsList | 2031 // -- r4 : argumentsList |
2033 // -- r3 : target | 2032 // -- r3 : target |
2034 // -- sp[0] : thisArgument | 2033 // -- sp[0] : thisArgument |
2035 // ----------------------------------- | 2034 // ----------------------------------- |
2036 | 2035 |
2037 // 2. Make sure the target is actually callable. | 2036 // 2. Make sure the target is actually callable. |
2038 Label target_not_callable; | 2037 Label target_not_callable; |
2039 __ JumpIfSmi(r3, &target_not_callable); | 2038 __ JumpIfSmi(r3, &target_not_callable); |
2040 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); | 2039 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); |
2041 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); | 2040 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); |
2042 __ TestBit(r6, Map::kIsCallable); | 2041 __ TestBit(r6, Map::kIsCallable); |
2043 __ beq(&target_not_callable); | 2042 __ beq(&target_not_callable); |
2044 | 2043 |
2045 // 3a. Apply the target to the given argumentsList (passing undefined for | 2044 // 3a. Apply the target to the given argumentsList. |
2046 // new.target). | 2045 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(), |
2047 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 2046 RelocInfo::CODE_TARGET); |
2048 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | |
2049 | 2047 |
2050 // 3b. The target is not callable, throw an appropriate TypeError. | 2048 // 3b. The target is not callable, throw an appropriate TypeError. |
2051 __ bind(&target_not_callable); | 2049 __ bind(&target_not_callable); |
2052 { | 2050 { |
2053 __ StoreP(r3, MemOperand(sp, 0)); | 2051 __ StoreP(r3, MemOperand(sp, 0)); |
2054 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 2052 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
2055 } | 2053 } |
2056 } | 2054 } |
2057 | 2055 |
2058 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 2056 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
2059 // ----------- S t a t e ------------- | 2057 // ----------- S t a t e ------------- |
2060 // -- r2 : argc | 2058 // -- r2 : argc |
2061 // -- sp[0] : new.target (optional) | 2059 // -- sp[0] : new.target (optional) |
2062 // -- sp[4] : argumentsList | 2060 // -- sp[4] : argumentsList |
2063 // -- sp[8] : target | 2061 // -- sp[8] : target |
2064 // -- sp[12] : receiver | 2062 // -- sp[12] : receiver |
2065 // ----------------------------------- | 2063 // ----------------------------------- |
2066 | 2064 |
2067 // 1. Load target into r3 (if present), argumentsList into r2 (if present), | 2065 // 1. Load target into r3 (if present), argumentsList into r4 (if present), |
2068 // new.target into r5 (if present, otherwise use target), remove all | 2066 // new.target into r5 (if present, otherwise use target), remove all |
2069 // arguments from the stack (including the receiver), and push thisArgument | 2067 // arguments from the stack (including the receiver), and push thisArgument |
2070 // (if present) instead. | 2068 // (if present) instead. |
2071 { | 2069 { |
2072 Label skip; | 2070 Label skip; |
2073 Register arg_size = r4; | 2071 Register arg_size = r7; |
2074 Register new_sp = r6; | 2072 Register new_sp = r6; |
2075 __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); | 2073 __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); |
2076 __ AddP(new_sp, sp, arg_size); | 2074 __ AddP(new_sp, sp, arg_size); |
2077 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 2075 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
2078 __ LoadRR(r2, r3); | 2076 __ LoadRR(r4, r3); |
2079 __ LoadRR(r5, r3); | 2077 __ LoadRR(r5, r3); |
2080 __ StoreP(r3, MemOperand(new_sp, 0)); // receiver (undefined) | 2078 __ StoreP(r3, MemOperand(new_sp, 0)); // receiver (undefined) |
2081 __ CmpP(arg_size, Operand(kPointerSize)); | 2079 __ CmpP(arg_size, Operand(kPointerSize)); |
2082 __ blt(&skip); | 2080 __ blt(&skip); |
2083 __ LoadP(r3, MemOperand(new_sp, 1 * -kPointerSize)); // target | 2081 __ LoadP(r3, MemOperand(new_sp, 1 * -kPointerSize)); // target |
2084 __ LoadRR(r5, r3); // new.target defaults to target | 2082 __ LoadRR(r5, r3); // new.target defaults to target |
2085 __ beq(&skip); | 2083 __ beq(&skip); |
2086 __ LoadP(r2, MemOperand(new_sp, 2 * -kPointerSize)); // argumentsList | 2084 __ LoadP(r4, MemOperand(new_sp, 2 * -kPointerSize)); // argumentsList |
2087 __ CmpP(arg_size, Operand(2 * kPointerSize)); | 2085 __ CmpP(arg_size, Operand(2 * kPointerSize)); |
2088 __ beq(&skip); | 2086 __ beq(&skip); |
2089 __ LoadP(r5, MemOperand(new_sp, 3 * -kPointerSize)); // new.target | 2087 __ LoadP(r5, MemOperand(new_sp, 3 * -kPointerSize)); // new.target |
2090 __ bind(&skip); | 2088 __ bind(&skip); |
2091 __ LoadRR(sp, new_sp); | 2089 __ LoadRR(sp, new_sp); |
2092 } | 2090 } |
2093 | 2091 |
2094 // ----------- S t a t e ------------- | 2092 // ----------- S t a t e ------------- |
2095 // -- r2 : argumentsList | 2093 // -- r4 : argumentsList |
2096 // -- r5 : new.target | 2094 // -- r5 : new.target |
2097 // -- r3 : target | 2095 // -- r3 : target |
2098 // -- sp[0] : receiver (undefined) | 2096 // -- sp[0] : receiver (undefined) |
2099 // ----------------------------------- | 2097 // ----------------------------------- |
2100 | 2098 |
2101 // 2. Make sure the target is actually a constructor. | 2099 // 2. Make sure the target is actually a constructor. |
2102 Label target_not_constructor; | 2100 Label target_not_constructor; |
2103 __ JumpIfSmi(r3, &target_not_constructor); | 2101 __ JumpIfSmi(r3, &target_not_constructor); |
2104 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); | 2102 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); |
2105 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); | 2103 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); |
2106 __ TestBit(r6, Map::kIsConstructor); | 2104 __ TestBit(r6, Map::kIsConstructor); |
2107 __ beq(&target_not_constructor); | 2105 __ beq(&target_not_constructor); |
2108 | 2106 |
2109 // 3. Make sure the target is actually a constructor. | 2107 // 3. Make sure the target is actually a constructor. |
2110 Label new_target_not_constructor; | 2108 Label new_target_not_constructor; |
2111 __ JumpIfSmi(r5, &new_target_not_constructor); | 2109 __ JumpIfSmi(r5, &new_target_not_constructor); |
2112 __ LoadP(r6, FieldMemOperand(r5, HeapObject::kMapOffset)); | 2110 __ LoadP(r6, FieldMemOperand(r5, HeapObject::kMapOffset)); |
2113 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); | 2111 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); |
2114 __ TestBit(r6, Map::kIsConstructor); | 2112 __ TestBit(r6, Map::kIsConstructor); |
2115 __ beq(&new_target_not_constructor); | 2113 __ beq(&new_target_not_constructor); |
2116 | 2114 |
2117 // 4a. Construct the target with the given new.target and argumentsList. | 2115 // 4a. Construct the target with the given new.target and argumentsList. |
2118 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 2116 __ Jump(masm->isolate()->builtins()->ConstructWithArrayLike(), |
| 2117 RelocInfo::CODE_TARGET); |
2119 | 2118 |
2120 // 4b. The target is not a constructor, throw an appropriate TypeError. | 2119 // 4b. The target is not a constructor, throw an appropriate TypeError. |
2121 __ bind(&target_not_constructor); | 2120 __ bind(&target_not_constructor); |
2122 { | 2121 { |
2123 __ StoreP(r3, MemOperand(sp, 0)); | 2122 __ StoreP(r3, MemOperand(sp, 0)); |
2124 __ TailCallRuntime(Runtime::kThrowNotConstructor); | 2123 __ TailCallRuntime(Runtime::kThrowNotConstructor); |
2125 } | 2124 } |
2126 | 2125 |
2127 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 2126 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
2128 __ bind(&new_target_not_constructor); | 2127 __ bind(&new_target_not_constructor); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 // then tear down the parameters. | 2162 // then tear down the parameters. |
2164 __ LoadP(r3, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 2163 __ LoadP(r3, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
2165 kPointerSize))); | 2164 kPointerSize))); |
2166 int stack_adjustment = kPointerSize; // adjust for receiver | 2165 int stack_adjustment = kPointerSize; // adjust for receiver |
2167 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); | 2166 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); |
2168 __ SmiToPtrArrayOffset(r3, r3); | 2167 __ SmiToPtrArrayOffset(r3, r3); |
2169 __ lay(sp, MemOperand(sp, r3)); | 2168 __ lay(sp, MemOperand(sp, r3)); |
2170 } | 2169 } |
2171 | 2170 |
2172 // static | 2171 // static |
2173 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2172 void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, |
| 2173 Handle<Code> code) { |
2174 // ----------- S t a t e ------------- | 2174 // ----------- S t a t e ------------- |
2175 // -- r2 : argumentsList | 2175 // -- r3 : target |
2176 // -- r3 : target | 2176 // -- r2 : number of parameters on the stack (not including the receiver) |
2177 // -- r5 : new.target (checked to be constructor or undefined) | 2177 // -- r4 : arguments list (a FixedArray) |
2178 // -- sp[0] : thisArgument | 2178 // -- r6 : len (number of elements to push from args) |
| 2179 // -- r5 : new.target (for [[Construct]]) |
2179 // ----------------------------------- | 2180 // ----------------------------------- |
2180 | 2181 |
2181 // Create the list of arguments from the array-like argumentsList. | 2182 __ AssertFixedArray(r4); |
2182 { | |
2183 Label create_arguments, create_array, create_holey_array, create_runtime, | |
2184 done_create; | |
2185 __ JumpIfSmi(r2, &create_runtime); | |
2186 | |
2187 // Load the map of argumentsList into r4. | |
2188 __ LoadP(r4, FieldMemOperand(r2, HeapObject::kMapOffset)); | |
2189 | |
2190 // Load native context into r6. | |
2191 __ LoadP(r6, NativeContextMemOperand()); | |
2192 | |
2193 // Check if argumentsList is an (unmodified) arguments object. | |
2194 __ LoadP(ip, ContextMemOperand(r6, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | |
2195 __ CmpP(ip, r4); | |
2196 __ beq(&create_arguments); | |
2197 __ LoadP(ip, ContextMemOperand(r6, Context::STRICT_ARGUMENTS_MAP_INDEX)); | |
2198 __ CmpP(ip, r4); | |
2199 __ beq(&create_arguments); | |
2200 | |
2201 // Check if argumentsList is a fast JSArray. | |
2202 __ CompareInstanceType(r4, ip, JS_ARRAY_TYPE); | |
2203 __ beq(&create_array); | |
2204 | |
2205 // Ask the runtime to create the list (actually a FixedArray). | |
2206 __ bind(&create_runtime); | |
2207 { | |
2208 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
2209 __ Push(r3, r5, r2); | |
2210 __ CallRuntime(Runtime::kCreateListFromArrayLike); | |
2211 __ Pop(r3, r5); | |
2212 __ LoadP(r4, FieldMemOperand(r2, FixedArray::kLengthOffset)); | |
2213 __ SmiUntag(r4); | |
2214 } | |
2215 __ b(&done_create); | |
2216 | |
2217 // Try to create the list from an arguments object. | |
2218 __ bind(&create_arguments); | |
2219 __ LoadP(r4, FieldMemOperand(r2, JSArgumentsObject::kLengthOffset)); | |
2220 __ LoadP(r6, FieldMemOperand(r2, JSObject::kElementsOffset)); | |
2221 __ LoadP(ip, FieldMemOperand(r6, FixedArray::kLengthOffset)); | |
2222 __ CmpP(r4, ip); | |
2223 __ bne(&create_runtime); | |
2224 __ SmiUntag(r4); | |
2225 __ LoadRR(r2, r6); | |
2226 __ b(&done_create); | |
2227 | |
2228 // For holey JSArrays we need to check that the array prototype chain | |
2229 // protector is intact and our prototype is the Array.prototype actually. | |
2230 __ bind(&create_holey_array); | |
2231 __ LoadP(r4, FieldMemOperand(r4, Map::kPrototypeOffset)); | |
2232 __ LoadP(r6, ContextMemOperand(r6, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); | |
2233 __ CmpP(r4, r6); | |
2234 __ bne(&create_runtime); | |
2235 __ LoadRoot(r6, Heap::kArrayProtectorRootIndex); | |
2236 __ LoadP(r4, FieldMemOperand(r6, PropertyCell::kValueOffset)); | |
2237 __ CmpSmiLiteral(r4, Smi::FromInt(Isolate::kProtectorValid), r0); | |
2238 __ bne(&create_runtime); | |
2239 __ LoadP(r4, FieldMemOperand(r2, JSArray::kLengthOffset)); | |
2240 __ LoadP(r2, FieldMemOperand(r2, JSArray::kElementsOffset)); | |
2241 __ SmiUntag(r4); | |
2242 __ b(&done_create); | |
2243 | |
2244 // Try to create the list from a JSArray object. | |
2245 // -- r4 and r6 must be preserved till bne create_holey_array. | |
2246 __ bind(&create_array); | |
2247 __ LoadlB(r7, FieldMemOperand(r4, Map::kBitField2Offset)); | |
2248 __ DecodeField<Map::ElementsKindBits>(r7); | |
2249 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
2250 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
2251 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
2252 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
2253 __ CmpP(r7, Operand(FAST_HOLEY_ELEMENTS)); | |
2254 __ bgt(&create_runtime); | |
2255 // Only FAST_XXX after this point, FAST_HOLEY_XXX are odd values. | |
2256 __ TestBit(r7, Map::kHasNonInstancePrototype, r0); | |
2257 __ bne(&create_holey_array); | |
2258 // FAST_SMI_ELEMENTS or FAST_ELEMENTS after this point. | |
2259 __ LoadP(r4, FieldMemOperand(r2, JSArray::kLengthOffset)); | |
2260 __ LoadP(r2, FieldMemOperand(r2, JSArray::kElementsOffset)); | |
2261 __ SmiUntag(r4); | |
2262 | |
2263 __ bind(&done_create); | |
2264 } | |
2265 | |
2266 // Check for stack overflow. | 2183 // Check for stack overflow. |
2267 { | 2184 { |
2268 // Check the stack for overflow. We are not trying to catch interruptions | 2185 // Check the stack for overflow. We are not trying to catch interruptions |
2269 // (i.e. debug break and preemption) here, so check the "real stack limit". | 2186 // (i.e. debug break and preemption) here, so check the "real stack limit". |
2270 Label done; | 2187 Label done; |
2271 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex); | 2188 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex); |
2272 // Make ip the space we have left. The stack might already be overflowed | 2189 // Make ip the space we have left. The stack might already be overflowed |
2273 // here which will cause ip to become negative. | 2190 // here which will cause ip to become negative. |
2274 __ SubP(ip, sp, ip); | 2191 __ SubP(ip, sp, ip); |
2275 // Check if the arguments will overflow the stack. | 2192 // Check if the arguments will overflow the stack. |
2276 __ ShiftLeftP(r0, r4, Operand(kPointerSizeLog2)); | 2193 __ ShiftLeftP(r0, r6, Operand(kPointerSizeLog2)); |
2277 __ CmpP(ip, r0); // Signed comparison. | 2194 __ CmpP(ip, r0); // Signed comparison. |
2278 __ bgt(&done); | 2195 __ bgt(&done); |
2279 __ TailCallRuntime(Runtime::kThrowStackOverflow); | 2196 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
2280 __ bind(&done); | 2197 __ bind(&done); |
2281 } | 2198 } |
2282 | 2199 |
2283 // ----------- S t a t e ------------- | |
2284 // -- r3 : target | |
2285 // -- r2 : args (a FixedArray built from argumentsList) | |
2286 // -- r4 : len (number of elements to push from args) | |
2287 // -- r5 : new.target (checked to be constructor or undefined) | |
2288 // -- sp[0] : thisArgument | |
2289 // ----------------------------------- | |
2290 | |
2291 // Push arguments onto the stack (thisArgument is already on the stack). | 2200 // Push arguments onto the stack (thisArgument is already on the stack). |
2292 { | 2201 { |
2293 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); | |
2294 Label loop, no_args, skip; | 2202 Label loop, no_args, skip; |
2295 __ CmpP(r4, Operand::Zero()); | 2203 __ CmpP(r6, Operand::Zero()); |
2296 __ beq(&no_args); | 2204 __ beq(&no_args); |
2297 __ AddP(r2, r2, | 2205 __ AddP(r4, r4, |
2298 Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); | 2206 Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); |
2299 __ LoadRR(r1, r4); | 2207 __ LoadRR(r1, r6); |
2300 __ bind(&loop); | 2208 __ bind(&loop); |
2301 __ LoadP(ip, MemOperand(r2, kPointerSize)); | 2209 __ LoadP(ip, MemOperand(r4, kPointerSize)); |
2302 __ la(r2, MemOperand(r2, kPointerSize)); | 2210 __ la(r4, MemOperand(r4, kPointerSize)); |
2303 __ CompareRoot(ip, Heap::kTheHoleValueRootIndex); | 2211 __ CompareRoot(ip, Heap::kTheHoleValueRootIndex); |
2304 __ bne(&skip, Label::kNear); | 2212 __ bne(&skip, Label::kNear); |
2305 __ LoadRR(ip, r8); | 2213 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
2306 __ bind(&skip); | 2214 __ bind(&skip); |
2307 __ push(ip); | 2215 __ push(ip); |
2308 __ BranchOnCount(r1, &loop); | 2216 __ BranchOnCount(r1, &loop); |
2309 __ bind(&no_args); | 2217 __ bind(&no_args); |
2310 __ LoadRR(r2, r4); | 2218 __ AddP(r2, r2, r6); |
2311 } | 2219 } |
2312 | 2220 |
2313 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2221 // Tail-call to the actual Call or Construct builtin. |
2314 { | 2222 __ Jump(code, RelocInfo::CODE_TARGET); |
2315 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex); | |
2316 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq); | |
2317 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | |
2318 } | |
2319 } | 2223 } |
2320 | 2224 |
2321 // static | 2225 // static |
2322 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, | 2226 void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, |
2323 Handle<Code> code) { | 2227 Handle<Code> code) { |
2324 // ----------- S t a t e ------------- | 2228 // ----------- S t a t e ------------- |
2325 // -- r2 : the number of arguments (not including the receiver) | 2229 // -- r2 : the number of arguments (not including the receiver) |
2326 // -- r5 : the new.target (for [[Construct]] calls) | 2230 // -- r5 : the new.target (for [[Construct]] calls) |
2327 // -- r3 : the target to call (can be any Object) | 2231 // -- r3 : the target to call (can be any Object) |
2328 // -- r4 : start index (to support rest parameters) | 2232 // -- r4 : start index (to support rest parameters) |
2329 // ----------------------------------- | 2233 // ----------------------------------- |
2330 | 2234 |
2331 // Check if we have an arguments adaptor frame below the function frame. | 2235 // Check if we have an arguments adaptor frame below the function frame. |
2332 Label arguments_adaptor, arguments_done; | 2236 Label arguments_adaptor, arguments_done; |
2333 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2237 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3244 // Now jump to the instructions of the returned code object. | 3148 // Now jump to the instructions of the returned code object. |
3245 __ Jump(ip); | 3149 __ Jump(ip); |
3246 } | 3150 } |
3247 | 3151 |
3248 #undef __ | 3152 #undef __ |
3249 | 3153 |
3250 } // namespace internal | 3154 } // namespace internal |
3251 } // namespace v8 | 3155 } // namespace v8 |
3252 | 3156 |
3253 #endif // V8_TARGET_ARCH_S390 | 3157 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |