| 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_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 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1194   __ JumpIfRoot(rax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear); |  1194   __ JumpIfRoot(rax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear); | 
|  1195   __ JumpIfRoot(rax, Heap::kUndefinedValueRootIndex, &no_arguments, |  1195   __ JumpIfRoot(rax, Heap::kUndefinedValueRootIndex, &no_arguments, | 
|  1196                 Label::kNear); |  1196                 Label::kNear); | 
|  1197  |  1197  | 
|  1198   // 4a. Apply the receiver to the given argArray (passing undefined for |  1198   // 4a. Apply the receiver to the given argArray (passing undefined for | 
|  1199   // new.target). |  1199   // new.target). | 
|  1200   __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |  1200   __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 
|  1201   __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |  1201   __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 
|  1202  |  1202  | 
|  1203   // 4b. The argArray is either null or undefined, so we tail call without any |  1203   // 4b. The argArray is either null or undefined, so we tail call without any | 
|  1204   // arguments to the receiver. |  1204   // arguments to the receiver. Since we did not create a frame for | 
 |  1205   // Function.prototype.apply() yet, we use a normal Call builtin here. | 
|  1205   __ bind(&no_arguments); |  1206   __ bind(&no_arguments); | 
|  1206   { |  1207   { | 
|  1207     __ Set(rax, 0); |  1208     __ Set(rax, 0); | 
|  1208     __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |  1209     __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 
|  1209   } |  1210   } | 
|  1210  |  1211  | 
|  1211   // 4c. The receiver is not callable, throw an appropriate TypeError. |  1212   // 4c. The receiver is not callable, throw an appropriate TypeError. | 
|  1212   __ bind(&receiver_not_callable); |  1213   __ bind(&receiver_not_callable); | 
|  1213   { |  1214   { | 
|  1214     StackArgumentsAccessor args(rsp, 0); |  1215     StackArgumentsAccessor args(rsp, 0); | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1258     __ bind(&loop); |  1259     __ bind(&loop); | 
|  1259     __ movp(rbx, args.GetArgumentOperand(1)); |  1260     __ movp(rbx, args.GetArgumentOperand(1)); | 
|  1260     __ movp(args.GetArgumentOperand(0), rbx); |  1261     __ movp(args.GetArgumentOperand(0), rbx); | 
|  1261     __ decp(rcx); |  1262     __ decp(rcx); | 
|  1262     __ j(not_zero, &loop);              // While non-zero. |  1263     __ j(not_zero, &loop);              // While non-zero. | 
|  1263     __ DropUnderReturnAddress(1, rbx);  // Drop one slot under return address. |  1264     __ DropUnderReturnAddress(1, rbx);  // Drop one slot under return address. | 
|  1264     __ decp(rax);  // One fewer argument (first argument is new receiver). |  1265     __ decp(rax);  // One fewer argument (first argument is new receiver). | 
|  1265   } |  1266   } | 
|  1266  |  1267  | 
|  1267   // 4. Call the callable. |  1268   // 4. Call the callable. | 
 |  1269   // Since we did not create a frame for Function.prototype.call() yet, | 
 |  1270   // we use a normal Call builtin here. | 
|  1268   __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |  1271   __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 
|  1269 } |  1272 } | 
|  1270  |  1273  | 
|  1271  |  1274  | 
|  1272 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |  1275 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 
|  1273   // ----------- S t a t e ------------- |  1276   // ----------- S t a t e ------------- | 
|  1274   //  -- rax     : argc |  1277   //  -- rax     : argc | 
|  1275   //  -- rsp[0]  : return address |  1278   //  -- rsp[0]  : return address | 
|  1276   //  -- rsp[8]  : argumentsList |  1279   //  -- rsp[8]  : argumentsList | 
|  1277   //  -- rsp[16] : thisArgument |  1280   //  -- rsp[16] : thisArgument | 
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2038   } |  2041   } | 
|  2039  |  2042  | 
|  2040   // Dispatch to Call or Construct depending on whether new.target is undefined. |  2043   // Dispatch to Call or Construct depending on whether new.target is undefined. | 
|  2041   { |  2044   { | 
|  2042     __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); |  2045     __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); | 
|  2043     __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |  2046     __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 
|  2044     __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |  2047     __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 
|  2045   } |  2048   } | 
|  2046 } |  2049 } | 
|  2047  |  2050  | 
 |  2051 namespace { | 
 |  2052  | 
 |  2053 // Drops top JavaScript frame and an arguments adaptor frame below it (if | 
 |  2054 // present) preserving all the arguments prepared for current call. | 
 |  2055 // Does nothing if debugger is currently active. | 
 |  2056 // ES6 14.6.3. PrepareForTailCall | 
 |  2057 // | 
 |  2058 // Stack structure for the function g() tail calling f(): | 
 |  2059 // | 
 |  2060 // ------- Caller frame: ------- | 
 |  2061 // |  ... | 
 |  2062 // |  g()'s arg M | 
 |  2063 // |  ... | 
 |  2064 // |  g()'s arg 1 | 
 |  2065 // |  g()'s receiver arg | 
 |  2066 // |  g()'s caller pc | 
 |  2067 // ------- g()'s frame: ------- | 
 |  2068 // |  g()'s caller fp      <- fp | 
 |  2069 // |  g()'s context | 
 |  2070 // |  function pointer: g | 
 |  2071 // |  ------------------------- | 
 |  2072 // |  ... | 
 |  2073 // |  ... | 
 |  2074 // |  f()'s arg N | 
 |  2075 // |  ... | 
 |  2076 // |  f()'s arg 1 | 
 |  2077 // |  f()'s receiver arg | 
 |  2078 // |  f()'s caller pc      <- sp | 
 |  2079 // ---------------------- | 
 |  2080 // | 
 |  2081 void PrepareForTailCall(MacroAssembler* masm, Register args_reg, | 
 |  2082                         Register scratch1, Register scratch2, | 
 |  2083                         Register scratch3) { | 
 |  2084   DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); | 
 |  2085   Comment cmnt(masm, "[ PrepareForTailCall"); | 
 |  2086  | 
 |  2087   // Prepare for tail call only if the debugger is not active. | 
 |  2088   Label done; | 
 |  2089   ExternalReference debug_is_active = | 
 |  2090       ExternalReference::debug_is_active_address(masm->isolate()); | 
 |  2091   __ Move(kScratchRegister, debug_is_active); | 
 |  2092   __ cmpb(Operand(kScratchRegister, 0), Immediate(0)); | 
 |  2093   __ j(not_equal, &done, Label::kNear); | 
 |  2094  | 
 |  2095   // Check if next frame is an arguments adaptor frame. | 
 |  2096   Label no_arguments_adaptor, formal_parameter_count_loaded; | 
 |  2097   __ movp(scratch2, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
 |  2098   __ Cmp(Operand(scratch2, StandardFrameConstants::kContextOffset), | 
 |  2099          Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
 |  2100   __ j(not_equal, &no_arguments_adaptor, Label::kNear); | 
 |  2101  | 
 |  2102   // Drop arguments adaptor frame and load arguments count. | 
 |  2103   __ movp(rbp, scratch2); | 
 |  2104   __ SmiToInteger32( | 
 |  2105       scratch1, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
 |  2106   __ jmp(&formal_parameter_count_loaded, Label::kNear); | 
 |  2107  | 
 |  2108   __ bind(&no_arguments_adaptor); | 
 |  2109   // Load caller's formal parameter count | 
 |  2110   __ movp(scratch1, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 
 |  2111   __ movp(scratch1, | 
 |  2112           FieldOperand(scratch1, JSFunction::kSharedFunctionInfoOffset)); | 
 |  2113   __ LoadSharedFunctionInfoSpecialField( | 
 |  2114       scratch1, scratch1, SharedFunctionInfo::kFormalParameterCountOffset); | 
 |  2115  | 
 |  2116   __ bind(&formal_parameter_count_loaded); | 
 |  2117  | 
 |  2118   // Calculate the destination address where we will put the return address | 
 |  2119   // after we drop current frame. | 
 |  2120   Register new_sp_reg = scratch2; | 
 |  2121   __ subp(scratch1, args_reg); | 
 |  2122   __ leap(new_sp_reg, Operand(rbp, scratch1, times_pointer_size, | 
 |  2123                               StandardFrameConstants::kCallerPCOffset)); | 
 |  2124  | 
 |  2125   if (FLAG_debug_code) { | 
 |  2126     __ cmpp(rsp, new_sp_reg); | 
 |  2127     __ Check(below, kStackAccessBelowStackPointer); | 
 |  2128   } | 
 |  2129  | 
 |  2130   // Copy receiver and return address as well. | 
 |  2131   Register count_reg = scratch1; | 
 |  2132   __ leap(count_reg, Operand(args_reg, 2)); | 
 |  2133  | 
 |  2134   // Copy return address from caller's frame to current frame's return address | 
 |  2135   // to avoid its trashing and let the following loop copy it to the right | 
 |  2136   // place. | 
 |  2137   Register tmp_reg = scratch3; | 
 |  2138   __ movp(tmp_reg, Operand(rbp, StandardFrameConstants::kCallerPCOffset)); | 
 |  2139   __ movp(Operand(rsp, 0), tmp_reg); | 
 |  2140  | 
 |  2141   // Restore caller's frame pointer now as it could be overwritten by | 
 |  2142   // the copying loop. | 
 |  2143   __ movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
 |  2144  | 
 |  2145   Operand src(rsp, count_reg, times_pointer_size, 0); | 
 |  2146   Operand dst(new_sp_reg, count_reg, times_pointer_size, 0); | 
 |  2147  | 
 |  2148   // Now copy callee arguments to the caller frame going backwards to avoid | 
 |  2149   // callee arguments corruption (source and destination areas could overlap). | 
 |  2150   Label loop, entry; | 
 |  2151   __ jmp(&entry, Label::kNear); | 
 |  2152   __ bind(&loop); | 
 |  2153   __ decp(count_reg); | 
 |  2154   __ movp(tmp_reg, src); | 
 |  2155   __ movp(dst, tmp_reg); | 
 |  2156   __ bind(&entry); | 
 |  2157   __ cmpp(count_reg, Immediate(0)); | 
 |  2158   __ j(not_equal, &loop, Label::kNear); | 
 |  2159  | 
 |  2160   // Leave current frame. | 
 |  2161   __ movp(rsp, new_sp_reg); | 
 |  2162  | 
 |  2163   __ bind(&done); | 
 |  2164 } | 
 |  2165 }  // namespace | 
|  2048  |  2166  | 
|  2049 // static |  2167 // static | 
|  2050 void Builtins::Generate_CallFunction(MacroAssembler* masm, |  2168 void Builtins::Generate_CallFunction(MacroAssembler* masm, | 
|  2051                                      ConvertReceiverMode mode) { |  2169                                      ConvertReceiverMode mode, | 
 |  2170                                      TailCallMode tail_call_mode) { | 
|  2052   // ----------- S t a t e ------------- |  2171   // ----------- S t a t e ------------- | 
|  2053   //  -- rax : the number of arguments (not including the receiver) |  2172   //  -- rax : the number of arguments (not including the receiver) | 
|  2054   //  -- rdi : the function to call (checked to be a JSFunction) |  2173   //  -- rdi : the function to call (checked to be a JSFunction) | 
|  2055   // ----------------------------------- |  2174   // ----------------------------------- | 
|  2056   StackArgumentsAccessor args(rsp, rax); |  2175   StackArgumentsAccessor args(rsp, rax); | 
|  2057   __ AssertFunction(rdi); |  2176   __ AssertFunction(rdi); | 
|  2058  |  2177  | 
|  2059   // ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) |  2178   // ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) | 
|  2060   // Check that the function is not a "classConstructor". |  2179   // Check that the function is not a "classConstructor". | 
|  2061   Label class_constructor; |  2180   Label class_constructor; | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2137   } |  2256   } | 
|  2138   __ bind(&done_convert); |  2257   __ bind(&done_convert); | 
|  2139  |  2258  | 
|  2140   // ----------- S t a t e ------------- |  2259   // ----------- S t a t e ------------- | 
|  2141   //  -- rax : the number of arguments (not including the receiver) |  2260   //  -- rax : the number of arguments (not including the receiver) | 
|  2142   //  -- rdx : the shared function info. |  2261   //  -- rdx : the shared function info. | 
|  2143   //  -- rdi : the function to call (checked to be a JSFunction) |  2262   //  -- rdi : the function to call (checked to be a JSFunction) | 
|  2144   //  -- rsi : the function context. |  2263   //  -- rsi : the function context. | 
|  2145   // ----------------------------------- |  2264   // ----------------------------------- | 
|  2146  |  2265  | 
 |  2266   if (tail_call_mode == TailCallMode::kAllow) { | 
 |  2267     PrepareForTailCall(masm, rax, rbx, rcx, r8); | 
 |  2268   } | 
 |  2269  | 
|  2147   __ LoadSharedFunctionInfoSpecialField( |  2270   __ LoadSharedFunctionInfoSpecialField( | 
|  2148       rbx, rdx, SharedFunctionInfo::kFormalParameterCountOffset); |  2271       rbx, rdx, SharedFunctionInfo::kFormalParameterCountOffset); | 
|  2149   ParameterCount actual(rax); |  2272   ParameterCount actual(rax); | 
|  2150   ParameterCount expected(rbx); |  2273   ParameterCount expected(rbx); | 
|  2151  |  2274  | 
|  2152   __ InvokeFunctionCode(rdi, no_reg, expected, actual, JUMP_FUNCTION, |  2275   __ InvokeFunctionCode(rdi, no_reg, expected, actual, JUMP_FUNCTION, | 
|  2153                         CheckDebugStepCallWrapper()); |  2276                         CheckDebugStepCallWrapper()); | 
|  2154  |  2277  | 
|  2155   // The function is a "classConstructor", need to raise an exception. |  2278   // The function is a "classConstructor", need to raise an exception. | 
|  2156   __ bind(&class_constructor); |  2279   __ bind(&class_constructor); | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2241     // [[BoundArguments]]), so we need to subtract one for the return address. |  2364     // [[BoundArguments]]), so we need to subtract one for the return address. | 
|  2242     __ decl(rax); |  2365     __ decl(rax); | 
|  2243   } |  2366   } | 
|  2244   __ bind(&no_bound_arguments); |  2367   __ bind(&no_bound_arguments); | 
|  2245 } |  2368 } | 
|  2246  |  2369  | 
|  2247 }  // namespace |  2370 }  // namespace | 
|  2248  |  2371  | 
|  2249  |  2372  | 
|  2250 // static |  2373 // static | 
|  2251 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) { |  2374 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, | 
 |  2375                                               TailCallMode tail_call_mode) { | 
|  2252   // ----------- S t a t e ------------- |  2376   // ----------- S t a t e ------------- | 
|  2253   //  -- rax : the number of arguments (not including the receiver) |  2377   //  -- rax : the number of arguments (not including the receiver) | 
|  2254   //  -- rdi : the function to call (checked to be a JSBoundFunction) |  2378   //  -- rdi : the function to call (checked to be a JSBoundFunction) | 
|  2255   // ----------------------------------- |  2379   // ----------------------------------- | 
|  2256   __ AssertBoundFunction(rdi); |  2380   __ AssertBoundFunction(rdi); | 
|  2257  |  2381  | 
 |  2382   if (tail_call_mode == TailCallMode::kAllow) { | 
 |  2383     PrepareForTailCall(masm, rax, rbx, rcx, r8); | 
 |  2384   } | 
 |  2385  | 
|  2258   // Patch the receiver to [[BoundThis]]. |  2386   // Patch the receiver to [[BoundThis]]. | 
|  2259   StackArgumentsAccessor args(rsp, rax); |  2387   StackArgumentsAccessor args(rsp, rax); | 
|  2260   __ movp(rbx, FieldOperand(rdi, JSBoundFunction::kBoundThisOffset)); |  2388   __ movp(rbx, FieldOperand(rdi, JSBoundFunction::kBoundThisOffset)); | 
|  2261   __ movp(args.GetReceiverOperand(), rbx); |  2389   __ movp(args.GetReceiverOperand(), rbx); | 
|  2262  |  2390  | 
|  2263   // Push the [[BoundArguments]] onto the stack. |  2391   // Push the [[BoundArguments]] onto the stack. | 
|  2264   Generate_PushBoundArguments(masm); |  2392   Generate_PushBoundArguments(masm); | 
|  2265  |  2393  | 
|  2266   // Call the [[BoundTargetFunction]] via the Call builtin. |  2394   // Call the [[BoundTargetFunction]] via the Call builtin. | 
|  2267   __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); |  2395   __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); | 
|  2268   __ Load(rcx, |  2396   __ Load(rcx, | 
|  2269           ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate())); |  2397           ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate())); | 
|  2270   __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |  2398   __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 
|  2271   __ jmp(rcx); |  2399   __ jmp(rcx); | 
|  2272 } |  2400 } | 
|  2273  |  2401  | 
|  2274  |  2402  | 
|  2275 // static |  2403 // static | 
|  2276 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |  2404 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, | 
 |  2405                              TailCallMode tail_call_mode) { | 
|  2277   // ----------- S t a t e ------------- |  2406   // ----------- S t a t e ------------- | 
|  2278   //  -- rax : the number of arguments (not including the receiver) |  2407   //  -- rax : the number of arguments (not including the receiver) | 
|  2279   //  -- rdi : the target to call (can be any Object) |  2408   //  -- rdi : the target to call (can be any Object) | 
|  2280   // ----------------------------------- |  2409   // ----------------------------------- | 
|  2281   StackArgumentsAccessor args(rsp, rax); |  2410   StackArgumentsAccessor args(rsp, rax); | 
|  2282  |  2411  | 
|  2283   Label non_callable, non_function, non_smi; |  2412   Label non_callable, non_function, non_smi; | 
|  2284   __ JumpIfSmi(rdi, &non_callable); |  2413   __ JumpIfSmi(rdi, &non_callable); | 
|  2285   __ bind(&non_smi); |  2414   __ bind(&non_smi); | 
|  2286   __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |  2415   __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 
|  2287   __ j(equal, masm->isolate()->builtins()->CallFunction(mode), |  2416   __ j(equal, masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), | 
|  2288        RelocInfo::CODE_TARGET); |  2417        RelocInfo::CODE_TARGET); | 
|  2289   __ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE); |  2418   __ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE); | 
|  2290   __ j(equal, masm->isolate()->builtins()->CallBoundFunction(), |  2419   __ j(equal, masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), | 
|  2291        RelocInfo::CODE_TARGET); |  2420        RelocInfo::CODE_TARGET); | 
|  2292   __ CmpInstanceType(rcx, JS_PROXY_TYPE); |  2421   __ CmpInstanceType(rcx, JS_PROXY_TYPE); | 
|  2293   __ j(not_equal, &non_function); |  2422   __ j(not_equal, &non_function); | 
|  2294  |  2423  | 
 |  2424   // 0. Prepare for tail call if necessary. | 
 |  2425   if (tail_call_mode == TailCallMode::kAllow) { | 
 |  2426     PrepareForTailCall(masm, rax, rbx, rcx, r8); | 
 |  2427   } | 
 |  2428  | 
|  2295   // 1. Runtime fallback for Proxy [[Call]]. |  2429   // 1. Runtime fallback for Proxy [[Call]]. | 
|  2296   __ PopReturnAddressTo(kScratchRegister); |  2430   __ PopReturnAddressTo(kScratchRegister); | 
|  2297   __ Push(rdi); |  2431   __ Push(rdi); | 
|  2298   __ PushReturnAddressFrom(kScratchRegister); |  2432   __ PushReturnAddressFrom(kScratchRegister); | 
|  2299   // Increase the arguments size to include the pushed function and the |  2433   // Increase the arguments size to include the pushed function and the | 
|  2300   // existing receiver on the stack. |  2434   // existing receiver on the stack. | 
|  2301   __ addp(rax, Immediate(2)); |  2435   __ addp(rax, Immediate(2)); | 
|  2302   // Tail-call to the runtime. |  2436   // Tail-call to the runtime. | 
|  2303   __ JumpToExternalReference( |  2437   __ JumpToExternalReference( | 
|  2304       ExternalReference(Runtime::kJSProxyCall, masm->isolate())); |  2438       ExternalReference(Runtime::kJSProxyCall, masm->isolate())); | 
|  2305  |  2439  | 
|  2306   // 2. Call to something else, which might have a [[Call]] internal method (if |  2440   // 2. Call to something else, which might have a [[Call]] internal method (if | 
|  2307   // not we raise an exception). |  2441   // not we raise an exception). | 
|  2308   __ bind(&non_function); |  2442   __ bind(&non_function); | 
|  2309   // Check if target has a [[Call]] internal method. |  2443   // Check if target has a [[Call]] internal method. | 
|  2310   __ testb(FieldOperand(rcx, Map::kBitFieldOffset), |  2444   __ testb(FieldOperand(rcx, Map::kBitFieldOffset), | 
|  2311            Immediate(1 << Map::kIsCallable)); |  2445            Immediate(1 << Map::kIsCallable)); | 
|  2312   __ j(zero, &non_callable, Label::kNear); |  2446   __ j(zero, &non_callable, Label::kNear); | 
|  2313   // Overwrite the original receiver with the (original) target. |  2447   // Overwrite the original receiver with the (original) target. | 
|  2314   __ movp(args.GetReceiverOperand(), rdi); |  2448   __ movp(args.GetReceiverOperand(), rdi); | 
|  2315   // Let the "call_as_function_delegate" take care of the rest. |  2449   // Let the "call_as_function_delegate" take care of the rest. | 
|  2316   __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, rdi); |  2450   __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, rdi); | 
|  2317   __ Jump(masm->isolate()->builtins()->CallFunction( |  2451   __ Jump(masm->isolate()->builtins()->CallFunction( | 
|  2318               ConvertReceiverMode::kNotNullOrUndefined), |  2452               ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), | 
|  2319           RelocInfo::CODE_TARGET); |  2453           RelocInfo::CODE_TARGET); | 
|  2320  |  2454  | 
|  2321   // 3. Call to something that is not callable. |  2455   // 3. Call to something that is not callable. | 
|  2322   __ bind(&non_callable); |  2456   __ bind(&non_callable); | 
|  2323   { |  2457   { | 
|  2324     FrameScope scope(masm, StackFrame::INTERNAL); |  2458     FrameScope scope(masm, StackFrame::INTERNAL); | 
|  2325     __ Push(rdi); |  2459     __ Push(rdi); | 
|  2326     __ CallRuntime(Runtime::kThrowCalledNonCallable); |  2460     __ CallRuntime(Runtime::kThrowCalledNonCallable); | 
|  2327   } |  2461   } | 
|  2328 } |  2462 } | 
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2619   __ ret(0); |  2753   __ ret(0); | 
|  2620 } |  2754 } | 
|  2621  |  2755  | 
|  2622  |  2756  | 
|  2623 #undef __ |  2757 #undef __ | 
|  2624  |  2758  | 
|  2625 }  // namespace internal |  2759 }  // namespace internal | 
|  2626 }  // namespace v8 |  2760 }  // namespace v8 | 
|  2627  |  2761  | 
|  2628 #endif  // V8_TARGET_ARCH_X64 |  2762 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |