OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_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 1899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1910 __ bind(&class_constructor); | 1910 __ bind(&class_constructor); |
1911 { | 1911 { |
1912 FrameScope frame(masm, StackFrame::INTERNAL); | 1912 FrameScope frame(masm, StackFrame::INTERNAL); |
1913 __ Push(a1); | 1913 __ Push(a1); |
1914 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); | 1914 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); |
1915 } | 1915 } |
1916 } | 1916 } |
1917 | 1917 |
1918 | 1918 |
1919 // static | 1919 // static |
| 1920 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) { |
| 1921 // ----------- S t a t e ------------- |
| 1922 // -- a0 : the number of arguments (not including the receiver) |
| 1923 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 1924 // ----------------------------------- |
| 1925 __ AssertBoundFunction(a1); |
| 1926 |
| 1927 // Patch the receiver to [[BoundThis]]. |
| 1928 { |
| 1929 __ ld(at, FieldMemOperand(a1, JSBoundFunction::kBoundThisOffset)); |
| 1930 __ dsll(a4, a0, kPointerSizeLog2); |
| 1931 __ daddu(a4, a4, sp); |
| 1932 __ sd(at, MemOperand(a4)); |
| 1933 } |
| 1934 |
| 1935 // Load [[BoundArguments]] into a2 and length of that into a4. |
| 1936 __ ld(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset)); |
| 1937 __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 1938 __ SmiUntag(a4); |
| 1939 |
| 1940 // ----------- S t a t e ------------- |
| 1941 // -- a0 : the number of arguments (not including the receiver) |
| 1942 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 1943 // -- a2 : the [[BoundArguments]] (implemented as FixedArray) |
| 1944 // -- a4 : the number of [[BoundArguments]] |
| 1945 // ----------------------------------- |
| 1946 |
| 1947 // Reserve stack space for the [[BoundArguments]]. |
| 1948 { |
| 1949 Label done; |
| 1950 __ dsll(a5, a4, kPointerSizeLog2); |
| 1951 __ Dsubu(sp, sp, Operand(a5)); |
| 1952 // Check the stack for overflow. We are not trying to catch interruptions |
| 1953 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 1954 __ LoadRoot(at, Heap::kRealStackLimitRootIndex); |
| 1955 __ Branch(&done, gt, sp, Operand(at)); // Signed comparison. |
| 1956 // Restore the stack pointer. |
| 1957 __ Daddu(sp, sp, Operand(a5)); |
| 1958 { |
| 1959 FrameScope scope(masm, StackFrame::MANUAL); |
| 1960 __ EnterFrame(StackFrame::INTERNAL); |
| 1961 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 1962 } |
| 1963 __ bind(&done); |
| 1964 } |
| 1965 |
| 1966 // Relocate arguments down the stack. |
| 1967 { |
| 1968 Label loop, done_loop; |
| 1969 __ mov(a5, zero_reg); |
| 1970 __ bind(&loop); |
| 1971 __ Branch(&done_loop, gt, a5, Operand(a0)); |
| 1972 __ dsll(a6, a4, kPointerSizeLog2); |
| 1973 __ daddu(a6, a6, sp); |
| 1974 __ ld(at, MemOperand(a6)); |
| 1975 __ dsll(a6, a5, kPointerSizeLog2); |
| 1976 __ daddu(a6, a6, sp); |
| 1977 __ sd(at, MemOperand(a6)); |
| 1978 __ Daddu(a4, a4, Operand(1)); |
| 1979 __ Daddu(a5, a5, Operand(1)); |
| 1980 __ Branch(&loop); |
| 1981 __ bind(&done_loop); |
| 1982 } |
| 1983 |
| 1984 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 1985 { |
| 1986 Label loop, done_loop; |
| 1987 __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 1988 __ SmiUntag(a4); |
| 1989 __ Daddu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1990 __ bind(&loop); |
| 1991 __ Dsubu(a4, a4, Operand(1)); |
| 1992 __ Branch(&done_loop, lt, a4, Operand(zero_reg)); |
| 1993 __ dsll(a5, a4, kPointerSizeLog2); |
| 1994 __ daddu(a5, a5, a2); |
| 1995 __ ld(at, MemOperand(a5)); |
| 1996 __ dsll(a5, a0, kPointerSizeLog2); |
| 1997 __ daddu(a5, a5, sp); |
| 1998 __ sd(at, MemOperand(a5)); |
| 1999 __ Daddu(a0, a0, Operand(1)); |
| 2000 __ Branch(&loop); |
| 2001 __ bind(&done_loop); |
| 2002 } |
| 2003 |
| 2004 // Call the [[BoundTargetFunction]] via the Call builtin. |
| 2005 __ ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2006 __ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, |
| 2007 masm->isolate()))); |
| 2008 __ ld(at, MemOperand(at)); |
| 2009 __ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2010 __ Jump(at); |
| 2011 } |
| 2012 |
| 2013 |
| 2014 // static |
1920 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { | 2015 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
1921 // ----------- S t a t e ------------- | 2016 // ----------- S t a t e ------------- |
1922 // -- a0 : the number of arguments (not including the receiver) | 2017 // -- a0 : the number of arguments (not including the receiver) |
1923 // -- a1 : the target to call (can be any Object). | 2018 // -- a1 : the target to call (can be any Object). |
1924 // ----------------------------------- | 2019 // ----------------------------------- |
1925 | 2020 |
1926 Label non_callable, non_function, non_smi; | 2021 Label non_callable, non_function, non_smi; |
1927 __ JumpIfSmi(a1, &non_callable); | 2022 __ JumpIfSmi(a1, &non_callable); |
1928 __ bind(&non_smi); | 2023 __ bind(&non_smi); |
1929 __ GetObjectType(a1, t1, t2); | 2024 __ GetObjectType(a1, t1, t2); |
1930 __ Jump(masm->isolate()->builtins()->CallFunction(mode), | 2025 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
1931 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); | 2026 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); |
| 2027 __ Jump(masm->isolate()->builtins()->CallBoundFunction(), |
| 2028 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE)); |
1932 __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); | 2029 __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); |
1933 | 2030 |
1934 // 1. Runtime fallback for Proxy [[Call]]. | 2031 // 1. Runtime fallback for Proxy [[Call]]. |
1935 __ Push(a1); | 2032 __ Push(a1); |
1936 // Increase the arguments size to include the pushed function and the | 2033 // Increase the arguments size to include the pushed function and the |
1937 // existing receiver on the stack. | 2034 // existing receiver on the stack. |
1938 __ Daddu(a0, a0, 2); | 2035 __ Daddu(a0, a0, 2); |
1939 // Tail-call to the runtime. | 2036 // Tail-call to the runtime. |
1940 __ JumpToExternalReference( | 2037 __ JumpToExternalReference( |
1941 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); | 2038 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1982 // Tail call to the function-specific construct stub (still in the caller | 2079 // Tail call to the function-specific construct stub (still in the caller |
1983 // context at this point). | 2080 // context at this point). |
1984 __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 2081 __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1985 __ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset)); | 2082 __ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset)); |
1986 __ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2083 __ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
1987 __ Jump(at); | 2084 __ Jump(at); |
1988 } | 2085 } |
1989 | 2086 |
1990 | 2087 |
1991 // static | 2088 // static |
| 2089 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
| 2090 // ----------- S t a t e ------------- |
| 2091 // -- a0 : the number of arguments (not including the receiver) |
| 2092 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 2093 // -- a3 : the new target (checked to be a constructor) |
| 2094 // ----------------------------------- |
| 2095 __ AssertBoundFunction(a1); |
| 2096 |
| 2097 // Load [[BoundArguments]] into a2 and length of that into a4. |
| 2098 __ ld(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset)); |
| 2099 __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 2100 __ SmiUntag(a4); |
| 2101 |
| 2102 // ----------- S t a t e ------------- |
| 2103 // -- a0 : the number of arguments (not including the receiver) |
| 2104 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 2105 // -- a2 : the [[BoundArguments]] (implemented as FixedArray) |
| 2106 // -- a3 : the new target (checked to be a constructor) |
| 2107 // -- a4 : the number of [[BoundArguments]] |
| 2108 // ----------------------------------- |
| 2109 |
| 2110 // Reserve stack space for the [[BoundArguments]]. |
| 2111 { |
| 2112 Label done; |
| 2113 __ dsll(a5, a4, kPointerSizeLog2); |
| 2114 __ Dsubu(sp, sp, Operand(a5)); |
| 2115 // Check the stack for overflow. We are not trying to catch interruptions |
| 2116 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 2117 __ LoadRoot(at, Heap::kRealStackLimitRootIndex); |
| 2118 __ Branch(&done, gt, sp, Operand(at)); // Signed comparison. |
| 2119 // Restore the stack pointer. |
| 2120 __ Daddu(sp, sp, Operand(a5)); |
| 2121 { |
| 2122 FrameScope scope(masm, StackFrame::MANUAL); |
| 2123 __ EnterFrame(StackFrame::INTERNAL); |
| 2124 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 2125 } |
| 2126 __ bind(&done); |
| 2127 } |
| 2128 |
| 2129 // Relocate arguments down the stack. |
| 2130 { |
| 2131 Label loop, done_loop; |
| 2132 __ mov(a5, zero_reg); |
| 2133 __ bind(&loop); |
| 2134 __ Branch(&done_loop, ge, a5, Operand(a0)); |
| 2135 __ dsll(a6, a4, kPointerSizeLog2); |
| 2136 __ daddu(a6, a6, sp); |
| 2137 __ ld(at, MemOperand(a6)); |
| 2138 __ dsll(a6, a5, kPointerSizeLog2); |
| 2139 __ daddu(a6, a6, sp); |
| 2140 __ sd(at, MemOperand(a6)); |
| 2141 __ Daddu(a4, a4, Operand(1)); |
| 2142 __ Daddu(a5, a5, Operand(1)); |
| 2143 __ Branch(&loop); |
| 2144 __ bind(&done_loop); |
| 2145 } |
| 2146 |
| 2147 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 2148 { |
| 2149 Label loop, done_loop; |
| 2150 __ ld(a4, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 2151 __ SmiUntag(a4); |
| 2152 __ Daddu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 2153 __ bind(&loop); |
| 2154 __ Dsubu(a4, a4, Operand(1)); |
| 2155 __ Branch(&done_loop, lt, a4, Operand(zero_reg)); |
| 2156 __ dsll(a5, a4, kPointerSizeLog2); |
| 2157 __ daddu(a5, a5, a2); |
| 2158 __ ld(at, MemOperand(a5)); |
| 2159 __ dsll(a5, a0, kPointerSizeLog2); |
| 2160 __ daddu(a5, a5, sp); |
| 2161 __ sd(at, MemOperand(a5)); |
| 2162 __ Daddu(a0, a0, Operand(1)); |
| 2163 __ Branch(&loop); |
| 2164 __ bind(&done_loop); |
| 2165 } |
| 2166 |
| 2167 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
| 2168 { |
| 2169 Label skip_load; |
| 2170 __ Branch(&skip_load, ne, a1, Operand(a3)); |
| 2171 __ ld(a3, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2172 __ bind(&skip_load); |
| 2173 } |
| 2174 |
| 2175 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
| 2176 __ ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2177 __ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); |
| 2178 __ ld(at, MemOperand(at)); |
| 2179 __ Addu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2180 __ Jump(at); |
| 2181 } |
| 2182 |
| 2183 |
| 2184 // static |
1992 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2185 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
1993 // ----------- S t a t e ------------- | 2186 // ----------- S t a t e ------------- |
1994 // -- a0 : the number of arguments (not including the receiver) | 2187 // -- a0 : the number of arguments (not including the receiver) |
1995 // -- a1 : the constructor to call (checked to be a JSProxy) | 2188 // -- a1 : the constructor to call (checked to be a JSProxy) |
1996 // -- a3 : the new target (either the same as the constructor or | 2189 // -- a3 : the new target (either the same as the constructor or |
1997 // the JSFunction on which new was invoked initially) | 2190 // the JSFunction on which new was invoked initially) |
1998 // ----------------------------------- | 2191 // ----------------------------------- |
1999 | 2192 |
2000 // Call into the Runtime for Proxy [[Construct]]. | 2193 // Call into the Runtime for Proxy [[Construct]]. |
2001 __ Push(a1, a3); | 2194 __ Push(a1, a3); |
(...skipping 22 matching lines...) Expand all Loading... |
2024 __ ld(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); | 2217 __ ld(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); |
2025 __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset)); | 2218 __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset)); |
2026 __ Jump(masm->isolate()->builtins()->ConstructFunction(), | 2219 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
2027 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); | 2220 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); |
2028 | 2221 |
2029 // Check if target has a [[Construct]] internal method. | 2222 // Check if target has a [[Construct]] internal method. |
2030 __ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset)); | 2223 __ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset)); |
2031 __ And(t3, t3, Operand(1 << Map::kIsCallable)); | 2224 __ And(t3, t3, Operand(1 << Map::kIsCallable)); |
2032 __ Branch(&non_constructor, eq, t3, Operand(zero_reg)); | 2225 __ Branch(&non_constructor, eq, t3, Operand(zero_reg)); |
2033 | 2226 |
| 2227 // Only dispatch to bound functions after checking whether they are |
| 2228 // constructors. |
| 2229 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(), |
| 2230 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE)); |
| 2231 |
2034 // Only dispatch to proxies after checking whether they are constructors. | 2232 // Only dispatch to proxies after checking whether they are constructors. |
2035 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, | 2233 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, |
2036 eq, t2, Operand(JS_PROXY_TYPE)); | 2234 eq, t2, Operand(JS_PROXY_TYPE)); |
2037 | 2235 |
2038 // Called Construct on an exotic Object with a [[Construct]] internal method. | 2236 // Called Construct on an exotic Object with a [[Construct]] internal method. |
2039 { | 2237 { |
2040 // Overwrite the original receiver with the (original) target. | 2238 // Overwrite the original receiver with the (original) target. |
2041 __ dsll(at, a0, kPointerSizeLog2); | 2239 __ dsll(at, a0, kPointerSizeLog2); |
2042 __ daddu(at, sp, at); | 2240 __ daddu(at, sp, at); |
2043 __ sd(a1, MemOperand(at)); | 2241 __ sd(a1, MemOperand(at)); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2209 } | 2407 } |
2210 } | 2408 } |
2211 | 2409 |
2212 | 2410 |
2213 #undef __ | 2411 #undef __ |
2214 | 2412 |
2215 } // namespace internal | 2413 } // namespace internal |
2216 } // namespace v8 | 2414 } // namespace v8 |
2217 | 2415 |
2218 #endif // V8_TARGET_ARCH_MIPS64 | 2416 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |