| 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/counters.h" | 9 #include "src/counters.h" |
| 10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
| (...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2409 | 2409 |
| 2410 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2410 // Dispatch to Call or Construct depending on whether new.target is undefined. |
| 2411 { | 2411 { |
| 2412 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); | 2412 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); |
| 2413 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2413 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2414 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2414 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2415 } | 2415 } |
| 2416 } | 2416 } |
| 2417 | 2417 |
| 2418 // static | 2418 // static |
| 2419 void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm, | 2419 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, |
| 2420 Handle<Code> code) { | 2420 Handle<Code> code) { |
| 2421 // ----------- S t a t e ------------- | 2421 // ----------- S t a t e ------------- |
| 2422 // -- rdi : the target to call (can be any Object) | 2422 // -- rax : the number of arguments (not including the receiver) |
| 2423 // -- rcx : start index (to support rest parameters) | 2423 // -- rdx : the new target (for [[Construct]] calls) |
| 2424 // -- rsp[0] : return address. | 2424 // -- rdi : the target to call (can be any Object) |
| 2425 // -- rsp[8] : thisArgument | 2425 // -- rcx : start index (to support rest parameters) |
| 2426 // ----------------------------------- | 2426 // ----------------------------------- |
| 2427 | 2427 |
| 2428 // Check if we have an arguments adaptor frame below the function frame. | 2428 // Check if we have an arguments adaptor frame below the function frame. |
| 2429 Label arguments_adaptor, arguments_done; | 2429 Label arguments_adaptor, arguments_done; |
| 2430 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2430 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 2431 __ cmpp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset), | 2431 __ cmpp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset), |
| 2432 Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); | 2432 Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2433 __ j(equal, &arguments_adaptor, Label::kNear); | 2433 __ j(equal, &arguments_adaptor, Label::kNear); |
| 2434 { | 2434 { |
| 2435 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 2435 __ movp(r8, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2436 __ movp(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset)); | 2436 __ movp(r8, FieldOperand(r8, JSFunction::kSharedFunctionInfoOffset)); |
| 2437 __ LoadSharedFunctionInfoSpecialField( | 2437 __ LoadSharedFunctionInfoSpecialField( |
| 2438 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset); | 2438 r8, r8, SharedFunctionInfo::kFormalParameterCountOffset); |
| 2439 __ movp(rbx, rbp); | 2439 __ movp(rbx, rbp); |
| 2440 } | 2440 } |
| 2441 __ jmp(&arguments_done, Label::kNear); | 2441 __ jmp(&arguments_done, Label::kNear); |
| 2442 __ bind(&arguments_adaptor); | 2442 __ bind(&arguments_adaptor); |
| 2443 { | 2443 { |
| 2444 __ SmiToInteger32( | 2444 __ SmiToInteger32( |
| 2445 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2445 r8, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2446 } | 2446 } |
| 2447 __ bind(&arguments_done); | 2447 __ bind(&arguments_done); |
| 2448 | 2448 |
| 2449 Label stack_empty, stack_done, stack_overflow; | 2449 Label stack_done, stack_overflow; |
| 2450 __ subl(rax, rcx); | 2450 __ subl(r8, rcx); |
| 2451 __ j(less_equal, &stack_empty); | 2451 __ j(less_equal, &stack_done); |
| 2452 { | 2452 { |
| 2453 // Check for stack overflow. | 2453 // Check for stack overflow. |
| 2454 Generate_StackOverflowCheck(masm, rax, rcx, &stack_overflow, Label::kNear); | 2454 Generate_StackOverflowCheck(masm, r8, rcx, &stack_overflow, Label::kNear); |
| 2455 | 2455 |
| 2456 // Forward the arguments from the caller frame. | 2456 // Forward the arguments from the caller frame. |
| 2457 { | 2457 { |
| 2458 Label loop; | 2458 Label loop; |
| 2459 __ movl(rcx, rax); | 2459 __ addl(rax, r8); |
| 2460 __ Pop(r8); | 2460 __ PopReturnAddressTo(rcx); |
| 2461 __ bind(&loop); | 2461 __ bind(&loop); |
| 2462 { | 2462 { |
| 2463 StackArgumentsAccessor args(rbx, rcx, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 2463 StackArgumentsAccessor args(rbx, r8, ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 2464 __ Push(args.GetArgumentOperand(0)); | 2464 __ Push(args.GetArgumentOperand(0)); |
| 2465 __ decl(rcx); | 2465 __ decl(r8); |
| 2466 __ j(not_zero, &loop); | 2466 __ j(not_zero, &loop); |
| 2467 } | 2467 } |
| 2468 __ Push(r8); | 2468 __ PushReturnAddressFrom(rcx); |
| 2469 } | 2469 } |
| 2470 } | 2470 } |
| 2471 __ jmp(&stack_done, Label::kNear); | 2471 __ jmp(&stack_done, Label::kNear); |
| 2472 __ bind(&stack_overflow); | 2472 __ bind(&stack_overflow); |
| 2473 __ TailCallRuntime(Runtime::kThrowStackOverflow); | 2473 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| 2474 __ bind(&stack_empty); | |
| 2475 { | |
| 2476 // We just pass the receiver, which is already on the stack. | |
| 2477 __ Set(rax, 0); | |
| 2478 } | |
| 2479 __ bind(&stack_done); | 2474 __ bind(&stack_done); |
| 2480 | 2475 |
| 2476 // Tail-call to the {code} handler. |
| 2481 __ Jump(code, RelocInfo::CODE_TARGET); | 2477 __ Jump(code, RelocInfo::CODE_TARGET); |
| 2482 } | 2478 } |
| 2483 | 2479 |
| 2484 namespace { | 2480 namespace { |
| 2485 | 2481 |
| 2486 // Drops top JavaScript frame and an arguments adaptor frame below it (if | 2482 // Drops top JavaScript frame and an arguments adaptor frame below it (if |
| 2487 // present) preserving all the arguments prepared for current call. | 2483 // present) preserving all the arguments prepared for current call. |
| 2488 // Does nothing if debugger is currently active. | 2484 // Does nothing if debugger is currently active. |
| 2489 // ES6 14.6.3. PrepareForTailCall | 2485 // ES6 14.6.3. PrepareForTailCall |
| 2490 // | 2486 // |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3239 // Now jump to the instructions of the returned code object. | 3235 // Now jump to the instructions of the returned code object. |
| 3240 __ jmp(r11); | 3236 __ jmp(r11); |
| 3241 } | 3237 } |
| 3242 | 3238 |
| 3243 #undef __ | 3239 #undef __ |
| 3244 | 3240 |
| 3245 } // namespace internal | 3241 } // namespace internal |
| 3246 } // namespace v8 | 3242 } // namespace v8 |
| 3247 | 3243 |
| 3248 #endif // V8_TARGET_ARCH_X64 | 3244 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |