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 |