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