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

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: [arm64] Poke does not preserve flags with --debug-code. 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
« no previous file with comments | « src/types.cc ('k') | src/x64/code-stubs-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_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 1955 matching lines...) Expand 10 before | Expand all | Expand 10 after
1966 // The function is a "classConstructor", need to raise an exception. 1966 // The function is a "classConstructor", need to raise an exception.
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 namespace {
1977
1978 void Generate_PushBoundArguments(MacroAssembler* masm) {
1979 // ----------- S t a t e -------------
1980 // -- rax : the number of arguments (not including the receiver)
1981 // -- rdx : new.target (only in case of [[Construct]])
1982 // -- rdi : target (checked to be a JSBoundFunction)
1983 // -----------------------------------
1984
1985 // Load [[BoundArguments]] into rcx and length of that into rbx.
1986 Label no_bound_arguments;
1987 __ movp(rcx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset));
1988 __ SmiToInteger32(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
1989 __ testl(rbx, rbx);
1990 __ j(zero, &no_bound_arguments);
1991 {
1992 // ----------- S t a t e -------------
1993 // -- rax : the number of arguments (not including the receiver)
1994 // -- rdx : new.target (only in case of [[Construct]])
1995 // -- rdi : target (checked to be a JSBoundFunction)
1996 // -- rcx : the [[BoundArguments]] (implemented as FixedArray)
1997 // -- rbx : the number of [[BoundArguments]] (checked to be non-zero)
1998 // -----------------------------------
1999
2000 // Reserve stack space for the [[BoundArguments]].
2001 {
2002 Label done;
2003 __ leap(kScratchRegister, Operand(rbx, times_pointer_size, 0));
2004 __ subp(rsp, kScratchRegister);
2005 // Check the stack for overflow. We are not trying to catch interruptions
2006 // (i.e. debug break and preemption) here, so check the "real stack
2007 // limit".
2008 __ CompareRoot(rsp, Heap::kRealStackLimitRootIndex);
2009 __ j(greater, &done, Label::kNear); // Signed comparison.
2010 // Restore the stack pointer.
2011 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, 0));
2012 {
2013 FrameScope scope(masm, StackFrame::MANUAL);
2014 __ EnterFrame(StackFrame::INTERNAL);
2015 __ CallRuntime(Runtime::kThrowStackOverflow, 0);
2016 }
2017 __ bind(&done);
2018 }
2019
2020 // Adjust effective number of arguments to include return address.
2021 __ incl(rax);
2022
2023 // Relocate arguments and return address down the stack.
2024 {
2025 Label loop;
2026 __ Set(rcx, 0);
2027 __ leap(rbx, Operand(rsp, rbx, times_pointer_size, 0));
2028 __ bind(&loop);
2029 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0));
2030 __ movp(Operand(rsp, rcx, times_pointer_size, 0), kScratchRegister);
2031 __ incl(rcx);
2032 __ cmpl(rcx, rax);
2033 __ j(less, &loop);
2034 }
2035
2036 // Copy [[BoundArguments]] to the stack (below the arguments).
2037 {
2038 Label loop;
2039 __ movp(rcx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset));
2040 __ SmiToInteger32(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
2041 __ bind(&loop);
2042 __ decl(rbx);
2043 __ movp(kScratchRegister, FieldOperand(rcx, rbx, times_pointer_size,
2044 FixedArray::kHeaderSize));
2045 __ movp(Operand(rsp, rax, times_pointer_size, 0), kScratchRegister);
2046 __ leal(rax, Operand(rax, 1));
2047 __ j(greater, &loop);
2048 }
2049
2050 // Adjust effective number of arguments (rax contains the number of
2051 // arguments from the call plus return address plus the number of
2052 // [[BoundArguments]]), so we need to subtract one for the return address.
2053 __ decl(rax);
2054 }
2055 __ bind(&no_bound_arguments);
2056 }
2057
2058 } // namespace
2059
2060
2061 // static
2062 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) {
2063 // ----------- S t a t e -------------
2064 // -- rax : the number of arguments (not including the receiver)
2065 // -- rdi : the function to call (checked to be a JSBoundFunction)
2066 // -----------------------------------
2067 __ AssertBoundFunction(rdi);
2068
2069 // Patch the receiver to [[BoundThis]].
2070 StackArgumentsAccessor args(rsp, rax);
2071 __ movp(rbx, FieldOperand(rdi, JSBoundFunction::kBoundThisOffset));
2072 __ movp(args.GetReceiverOperand(), rbx);
2073
2074 // Push the [[BoundArguments]] onto the stack.
2075 Generate_PushBoundArguments(masm);
2076
2077 // Call the [[BoundTargetFunction]] via the Call builtin.
2078 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
2079 __ Load(rcx,
2080 ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate()));
2081 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
2082 __ jmp(rcx);
2083 }
2084
2085
1976 // static 2086 // static
1977 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { 2087 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1978 // ----------- S t a t e ------------- 2088 // ----------- S t a t e -------------
1979 // -- rax : the number of arguments (not including the receiver) 2089 // -- rax : the number of arguments (not including the receiver)
1980 // -- rdi : the target to call (can be any Object) 2090 // -- rdi : the target to call (can be any Object)
1981 // ----------------------------------- 2091 // -----------------------------------
1982 StackArgumentsAccessor args(rsp, rax); 2092 StackArgumentsAccessor args(rsp, rax);
1983 2093
1984 Label non_callable, non_function, non_smi; 2094 Label non_callable, non_function, non_smi;
1985 __ JumpIfSmi(rdi, &non_callable); 2095 __ JumpIfSmi(rdi, &non_callable);
1986 __ bind(&non_smi); 2096 __ bind(&non_smi);
1987 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2097 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
1988 __ j(equal, masm->isolate()->builtins()->CallFunction(mode), 2098 __ j(equal, masm->isolate()->builtins()->CallFunction(mode),
1989 RelocInfo::CODE_TARGET); 2099 RelocInfo::CODE_TARGET);
2100 __ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE);
2101 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(),
2102 RelocInfo::CODE_TARGET);
1990 __ CmpInstanceType(rcx, JS_PROXY_TYPE); 2103 __ CmpInstanceType(rcx, JS_PROXY_TYPE);
1991 __ j(not_equal, &non_function); 2104 __ j(not_equal, &non_function);
1992 2105
1993 // 1. Runtime fallback for Proxy [[Call]]. 2106 // 1. Runtime fallback for Proxy [[Call]].
1994 __ PopReturnAddressTo(kScratchRegister); 2107 __ PopReturnAddressTo(kScratchRegister);
1995 __ Push(rdi); 2108 __ Push(rdi);
1996 __ PushReturnAddressFrom(kScratchRegister); 2109 __ PushReturnAddressFrom(kScratchRegister);
1997 // Increase the arguments size to include the pushed function and the 2110 // Increase the arguments size to include the pushed function and the
1998 // existing receiver on the stack. 2111 // existing receiver on the stack.
1999 __ addp(rax, Immediate(2)); 2112 __ 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 2155 // Tail call to the function-specific construct stub (still in the caller
2043 // context at this point). 2156 // context at this point).
2044 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 2157 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
2045 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); 2158 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
2046 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 2159 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
2047 __ jmp(rcx); 2160 __ jmp(rcx);
2048 } 2161 }
2049 2162
2050 2163
2051 // static 2164 // static
2165 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2166 // ----------- S t a t e -------------
2167 // -- rax : the number of arguments (not including the receiver)
2168 // -- rdx : the new target (checked to be a constructor)
2169 // -- rdi : the constructor to call (checked to be a JSBoundFunction)
2170 // -----------------------------------
2171 __ AssertBoundFunction(rdi);
2172
2173 // Push the [[BoundArguments]] onto the stack.
2174 Generate_PushBoundArguments(masm);
2175
2176 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2177 {
2178 Label done;
2179 __ cmpp(rdi, rdx);
2180 __ j(not_equal, &done, Label::kNear);
2181 __ movp(rdx,
2182 FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
2183 __ bind(&done);
2184 }
2185
2186 // Construct the [[BoundTargetFunction]] via the Construct builtin.
2187 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
2188 __ Load(rcx, ExternalReference(Builtins::kConstruct, masm->isolate()));
2189 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
2190 __ jmp(rcx);
2191 }
2192
2193
2194 // static
2052 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { 2195 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2053 // ----------- S t a t e ------------- 2196 // ----------- S t a t e -------------
2054 // -- rax : the number of arguments (not including the receiver) 2197 // -- rax : the number of arguments (not including the receiver)
2055 // -- rdi : the constructor to call (checked to be a JSProxy) 2198 // -- rdi : the constructor to call (checked to be a JSProxy)
2056 // -- rdx : the new target (either the same as the constructor or 2199 // -- rdx : the new target (either the same as the constructor or
2057 // the JSFunction on which new was invoked initially) 2200 // the JSFunction on which new was invoked initially)
2058 // ----------------------------------- 2201 // -----------------------------------
2059 2202
2060 // Call into the Runtime for Proxy [[Construct]]. 2203 // Call into the Runtime for Proxy [[Construct]].
2061 __ PopReturnAddressTo(kScratchRegister); 2204 __ PopReturnAddressTo(kScratchRegister);
(...skipping 24 matching lines...) Expand all
2086 // Dispatch based on instance type. 2229 // Dispatch based on instance type.
2087 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2230 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2088 __ j(equal, masm->isolate()->builtins()->ConstructFunction(), 2231 __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2089 RelocInfo::CODE_TARGET); 2232 RelocInfo::CODE_TARGET);
2090 2233
2091 // Check if target has a [[Construct]] internal method. 2234 // Check if target has a [[Construct]] internal method.
2092 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 2235 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
2093 Immediate(1 << Map::kIsConstructor)); 2236 Immediate(1 << Map::kIsConstructor));
2094 __ j(zero, &non_constructor, Label::kNear); 2237 __ j(zero, &non_constructor, Label::kNear);
2095 2238
2239 // Only dispatch to bound functions after checking whether they are
2240 // constructors.
2241 __ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE);
2242 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2243 RelocInfo::CODE_TARGET);
2244
2096 // Only dispatch to proxies after checking whether they are constructors. 2245 // Only dispatch to proxies after checking whether they are constructors.
2097 __ CmpInstanceType(rcx, JS_PROXY_TYPE); 2246 __ CmpInstanceType(rcx, JS_PROXY_TYPE);
2098 __ j(equal, masm->isolate()->builtins()->ConstructProxy(), 2247 __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
2099 RelocInfo::CODE_TARGET); 2248 RelocInfo::CODE_TARGET);
2100 2249
2101 // Called Construct on an exotic Object with a [[Construct]] internal method. 2250 // Called Construct on an exotic Object with a [[Construct]] internal method.
2102 { 2251 {
2103 // Overwrite the original receiver with the (original) target. 2252 // Overwrite the original receiver with the (original) target.
2104 __ movp(args.GetReceiverOperand(), rdi); 2253 __ movp(args.GetReceiverOperand(), rdi);
2105 // Let the "call_as_constructor_delegate" take care of the rest. 2254 // 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); 2445 __ ret(0);
2297 } 2446 }
2298 2447
2299 2448
2300 #undef __ 2449 #undef __
2301 2450
2302 } // namespace internal 2451 } // namespace internal
2303 } // namespace v8 2452 } // namespace v8
2304 2453
2305 #endif // V8_TARGET_ARCH_X64 2454 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « 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