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

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

Issue 1542963002: [runtime] Introduce dedicated JSBoundFunction to represent bound functions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@FunctionConstructor
Patch Set: arm port. Created 4 years, 12 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
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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.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 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 __ bind(&class_constructor); 1967 __ bind(&class_constructor);
1968 { 1968 {
1969 FrameScope frame(masm, StackFrame::INTERNAL); 1969 FrameScope frame(masm, StackFrame::INTERNAL);
1970 __ Push(rdi); 1970 __ Push(rdi);
1971 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); 1971 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
1972 } 1972 }
1973 } 1973 }
1974 1974
1975 1975
1976 // static 1976 // static
1977 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) {
1978 // ----------- S t a t e -------------
1979 // -- rax : the number of arguments (not including the receiver)
1980 // -- rdi : the function to call (checked to be a JSBoundFunction)
1981 // -----------------------------------
1982 __ AssertBoundFunction(rdi);
1983
1984 // Patch the receiver to [[BoundThis]].
1985 {
1986 StackArgumentsAccessor args(rsp, rax);
1987 __ movp(rbx, FieldOperand(rdi, JSBoundFunction::kBoundThisOffset));
1988 __ movp(args.GetReceiverOperand(), rbx);
1989 }
1990
1991 // Load [[BoundArguments]] into rdx and length of that into rcx.
1992 __ movp(rdx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset));
1993 __ SmiToInteger32(rcx, FieldOperand(rdx, FixedArray::kLengthOffset));
1994
1995 // ----------- S t a t e -------------
1996 // -- rax : the number of arguments (not including the receiver)
1997 // -- rdi : the function to call (checked to be a JSBoundFunction)
1998 // -- rdx : the [[BoundArguments]] (implemented as FixedArray)
1999 // -- rcx : the number of [[BoundArguments]]
2000 // -----------------------------------
2001
2002 // Reserve stack space for the [[BoundArguments]].
2003 {
2004 Label done;
2005 __ leap(rbx, Operand(rcx, times_pointer_size, 0));
2006 __ subp(rsp, rbx);
2007 // Check the stack for overflow. We are not trying to catch interruptions
2008 // (i.e. debug break and preemption) here, so check the "real stack limit".
2009 __ CompareRoot(rsp, Heap::kRealStackLimitRootIndex);
2010 __ j(greater, &done, Label::kNear); // Signed comparison.
2011 // Restore the stack pointer.
2012 __ addp(rsp, rbx);
2013 {
2014 FrameScope scope(masm, StackFrame::MANUAL);
2015 __ EnterFrame(StackFrame::INTERNAL);
2016 __ CallRuntime(Runtime::kThrowStackOverflow, 0);
2017 }
2018 __ bind(&done);
2019 }
2020
2021 // Relocate arguments and return address down the stack.
2022 {
2023 Label loop;
2024 __ incp(rax); // arguments plus return address
2025 __ Set(rbx, 0);
2026 __ bind(&loop);
2027 __ movp(kScratchRegister, Operand(rsp, rcx, times_pointer_size, 0));
2028 __ incp(rcx);
2029 __ movp(Operand(rsp, rbx, times_pointer_size, 0), kScratchRegister);
2030 __ incp(rbx);
2031 __ cmpp(rbx, rax);
2032 __ j(less, &loop);
2033 }
2034
2035 // Copy [[BoundArguments]] to the stack (below the arguments).
2036 {
2037 Label loop, done_loop;
2038 __ SmiToInteger32(rcx, FieldOperand(rdx, FixedArray::kLengthOffset));
2039 __ bind(&loop);
2040 __ subp(rcx, Immediate(1));
2041 __ j(less, &done_loop, Label::kNear);
2042 __ movp(rbx, FieldOperand(rdx, rcx, times_pointer_size,
2043 FixedArray::kHeaderSize));
2044 __ movp(Operand(rsp, rax, times_pointer_size, 0), rbx);
2045 __ incp(rax);
2046 __ jmp(&loop);
2047 __ bind(&done_loop);
2048 }
2049
2050 // Adjust effective number of arguments (rax contains the number of arguments
2051 // from the call plus return address plus the number of [[BoundArguments]]),
2052 // so we need to subtract one for the return address.
2053 __ decp(rax);
2054
2055 // Call the [[BoundTargetFunction]] via the Call builtin.
2056 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
2057 __ Load(rcx,
2058 ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate()));
2059 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
2060 __ jmp(rcx);
2061 }
2062
2063
2064 // static
1977 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { 2065 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1978 // ----------- S t a t e ------------- 2066 // ----------- S t a t e -------------
1979 // -- rax : the number of arguments (not including the receiver) 2067 // -- rax : the number of arguments (not including the receiver)
1980 // -- rdi : the target to call (can be any Object) 2068 // -- rdi : the target to call (can be any Object)
1981 // ----------------------------------- 2069 // -----------------------------------
1982 StackArgumentsAccessor args(rsp, rax); 2070 StackArgumentsAccessor args(rsp, rax);
1983 2071
1984 Label non_callable, non_function, non_smi; 2072 Label non_callable, non_function, non_smi;
1985 __ JumpIfSmi(rdi, &non_callable); 2073 __ JumpIfSmi(rdi, &non_callable);
1986 __ bind(&non_smi); 2074 __ bind(&non_smi);
1987 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2075 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
1988 __ j(equal, masm->isolate()->builtins()->CallFunction(mode), 2076 __ j(equal, masm->isolate()->builtins()->CallFunction(mode),
1989 RelocInfo::CODE_TARGET); 2077 RelocInfo::CODE_TARGET);
2078 __ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE);
2079 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(),
2080 RelocInfo::CODE_TARGET);
1990 __ CmpInstanceType(rcx, JS_PROXY_TYPE); 2081 __ CmpInstanceType(rcx, JS_PROXY_TYPE);
1991 __ j(not_equal, &non_function); 2082 __ j(not_equal, &non_function);
1992 2083
1993 // 1. Runtime fallback for Proxy [[Call]]. 2084 // 1. Runtime fallback for Proxy [[Call]].
1994 __ PopReturnAddressTo(kScratchRegister); 2085 __ PopReturnAddressTo(kScratchRegister);
1995 __ Push(rdi); 2086 __ Push(rdi);
1996 __ PushReturnAddressFrom(kScratchRegister); 2087 __ PushReturnAddressFrom(kScratchRegister);
1997 // Increase the arguments size to include the pushed function and the 2088 // Increase the arguments size to include the pushed function and the
1998 // existing receiver on the stack. 2089 // existing receiver on the stack.
1999 __ addp(rax, Immediate(2)); 2090 __ addp(rax, Immediate(2));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2042 // Tail call to the function-specific construct stub (still in the caller 2133 // Tail call to the function-specific construct stub (still in the caller
2043 // context at this point). 2134 // context at this point).
2044 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 2135 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
2045 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); 2136 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
2046 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 2137 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
2047 __ jmp(rcx); 2138 __ jmp(rcx);
2048 } 2139 }
2049 2140
2050 2141
2051 // static 2142 // static
2143 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2144 // ----------- S t a t e -------------
2145 // -- rax : the number of arguments (not including the receiver)
2146 // -- rdx : the new target (checked to be a constructor)
2147 // -- rdi : the constructor to call (checked to be a JSBoundFunction)
2148 // -----------------------------------
2149 __ AssertBoundFunction(rdi);
2150
2151 // Load [[BoundArguments]] into r12 and length of that into rcx.
2152 __ movp(r12, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset));
2153 __ SmiToInteger32(rcx, FieldOperand(r12, FixedArray::kLengthOffset));
2154
2155 // ----------- S t a t e -------------
2156 // -- rax : the number of arguments (not including the receiver)
2157 // -- rdi : the function to call (checked to be a JSBoundFunction)
2158 // -- r12 : the [[BoundArguments]] (implemented as FixedArray)
2159 // -- rcx : the number of [[BoundArguments]]
2160 // -----------------------------------
2161
2162 // Reserve stack space for the [[BoundArguments]].
2163 {
2164 Label done;
2165 __ leap(rbx, Operand(rcx, times_pointer_size, 0));
2166 __ subp(rsp, rbx);
2167 // Check the stack for overflow. We are not trying to catch interruptions
2168 // (i.e. debug break and preemption) here, so check the "real stack limit".
2169 __ CompareRoot(rsp, Heap::kRealStackLimitRootIndex);
2170 __ j(greater, &done, Label::kNear); // Signed comparison.
2171 // Restore the stack pointer.
2172 __ addp(rsp, rbx);
2173 {
2174 FrameScope scope(masm, StackFrame::MANUAL);
2175 __ EnterFrame(StackFrame::INTERNAL);
2176 __ CallRuntime(Runtime::kThrowStackOverflow, 0);
2177 }
2178 __ bind(&done);
2179 }
2180
2181 // Relocate arguments and return address down the stack.
2182 {
2183 Label loop;
2184 __ incp(rax); // arguments plus return address
2185 __ Set(rbx, 0);
2186 __ bind(&loop);
2187 __ movp(kScratchRegister, Operand(rsp, rcx, times_pointer_size, 0));
2188 __ incp(rcx);
2189 __ movp(Operand(rsp, rbx, times_pointer_size, 0), kScratchRegister);
2190 __ incp(rbx);
2191 __ cmpp(rbx, rax);
2192 __ j(less, &loop);
2193 }
2194
2195 // Copy [[BoundArguments]] to the stack (below the arguments).
2196 {
2197 Label loop, done_loop;
2198 __ SmiToInteger32(rcx, FieldOperand(r12, FixedArray::kLengthOffset));
2199 __ bind(&loop);
2200 __ subp(rcx, Immediate(1));
2201 __ j(less, &done_loop, Label::kNear);
2202 __ movp(rbx, FieldOperand(r12, rcx, times_pointer_size,
2203 FixedArray::kHeaderSize));
2204 __ movp(Operand(rsp, rax, times_pointer_size, 0), rbx);
2205 __ incp(rax);
2206 __ jmp(&loop);
2207 __ bind(&done_loop);
2208 }
2209
2210 // Adjust effective number of arguments (rax contains the number of arguments
2211 // from the call plus return address plus the number of [[BoundArguments]]),
2212 // so we need to subtract one for the return address.
2213 __ decp(rax);
Camillo Bruni 2015/12/23 13:52:27 Would it be possible to create a helper function u
Benedikt Meurer 2015/12/24 06:28:18 Done.
2214
2215 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2216 {
2217 Label done;
2218 __ cmpp(rdi, rdx);
2219 __ j(not_equal, &done, Label::kNear);
2220 __ movp(rdx,
2221 FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
2222 __ bind(&done);
2223 }
2224
2225 // Construct the [[BoundTargetFunction]] via the Construct builtin.
2226 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
2227 __ Load(rcx, ExternalReference(Builtins::kConstruct, masm->isolate()));
2228 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
2229 __ jmp(rcx);
2230 }
2231
2232
2233 // static
2052 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { 2234 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2053 // ----------- S t a t e ------------- 2235 // ----------- S t a t e -------------
2054 // -- rax : the number of arguments (not including the receiver) 2236 // -- rax : the number of arguments (not including the receiver)
2055 // -- rdi : the constructor to call (checked to be a JSProxy) 2237 // -- rdi : the constructor to call (checked to be a JSProxy)
2056 // -- rdx : the new target (either the same as the constructor or 2238 // -- rdx : the new target (either the same as the constructor or
2057 // the JSFunction on which new was invoked initially) 2239 // the JSFunction on which new was invoked initially)
2058 // ----------------------------------- 2240 // -----------------------------------
2059 2241
2060 // Call into the Runtime for Proxy [[Construct]]. 2242 // Call into the Runtime for Proxy [[Construct]].
2061 __ PopReturnAddressTo(kScratchRegister); 2243 __ PopReturnAddressTo(kScratchRegister);
(...skipping 24 matching lines...) Expand all
2086 // Dispatch based on instance type. 2268 // Dispatch based on instance type.
2087 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2269 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2088 __ j(equal, masm->isolate()->builtins()->ConstructFunction(), 2270 __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2089 RelocInfo::CODE_TARGET); 2271 RelocInfo::CODE_TARGET);
2090 2272
2091 // Check if target has a [[Construct]] internal method. 2273 // Check if target has a [[Construct]] internal method.
2092 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 2274 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
2093 Immediate(1 << Map::kIsConstructor)); 2275 Immediate(1 << Map::kIsConstructor));
2094 __ j(zero, &non_constructor, Label::kNear); 2276 __ j(zero, &non_constructor, Label::kNear);
2095 2277
2278 // Only dispatch to bound functions after checking whether they are
2279 // constructors.
2280 __ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE);
2281 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2282 RelocInfo::CODE_TARGET);
2283
2096 // Only dispatch to proxies after checking whether they are constructors. 2284 // Only dispatch to proxies after checking whether they are constructors.
2097 __ CmpInstanceType(rcx, JS_PROXY_TYPE); 2285 __ CmpInstanceType(rcx, JS_PROXY_TYPE);
2098 __ j(equal, masm->isolate()->builtins()->ConstructProxy(), 2286 __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
2099 RelocInfo::CODE_TARGET); 2287 RelocInfo::CODE_TARGET);
2100 2288
2101 // Called Construct on an exotic Object with a [[Construct]] internal method. 2289 // Called Construct on an exotic Object with a [[Construct]] internal method.
2102 { 2290 {
2103 // Overwrite the original receiver with the (original) target. 2291 // Overwrite the original receiver with the (original) target.
2104 __ movp(args.GetReceiverOperand(), rdi); 2292 __ movp(args.GetReceiverOperand(), rdi);
2105 // Let the "call_as_constructor_delegate" take care of the rest. 2293 // Let the "call_as_constructor_delegate" take care of the rest.
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 __ ret(0); 2484 __ ret(0);
2297 } 2485 }
2298 2486
2299 2487
2300 #undef __ 2488 #undef __
2301 2489
2302 } // namespace internal 2490 } // namespace internal
2303 } // namespace v8 2491 } // namespace v8
2304 2492
2305 #endif // V8_TARGET_ARCH_X64 2493 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/objects-inl.h ('K') | « src/types.cc ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698