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 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 __ Push(rbx); | 552 __ Push(rbx); |
553 __ Push(rdx); | 553 __ Push(rdx); |
554 __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator); | 554 __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator); |
555 __ Pop(rdx); | 555 __ Pop(rdx); |
556 __ Pop(rbx); | 556 __ Pop(rbx); |
557 __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); | 557 __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); |
558 } | 558 } |
559 __ jmp(&stepping_prepared); | 559 __ jmp(&stepping_prepared); |
560 } | 560 } |
561 | 561 |
| 562 // static |
| 563 void Builtins::Generate_ResumeAwaitedGeneratorTrampoline(MacroAssembler* masm) { |
| 564 // ----------- S t a t e ------------- |
| 565 // -- rax : the value to pass to the generator |
| 566 // -- rbx : the JSGeneratorObject to resume |
| 567 // -- rdx : the resume mode (tagged) |
| 568 // -- rsp[0] : return address |
| 569 // ----------------------------------- |
| 570 __ AssertGeneratorObject(rbx); |
| 571 |
| 572 // Restore saved input |
| 573 __ movp(rcx, FieldOperand(rbx, JSGeneratorObject::kAwaitInputOffset)); |
| 574 __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOrDebugPosOffset), rcx); |
| 575 __ RecordWriteField(rbx, JSGeneratorObject::kInputOrDebugPosOffset, rcx, rsi, |
| 576 kDontSaveFPRegs); |
| 577 |
| 578 // Store input value into generator object. |
| 579 __ movp(FieldOperand(rbx, JSGeneratorObject::kAwaitInputOffset), rax); |
| 580 __ RecordWriteField(rbx, JSGeneratorObject::kAwaitInputOffset, rax, rcx, |
| 581 kDontSaveFPRegs); |
| 582 |
| 583 // Store resume mode into generator object. |
| 584 __ movp(FieldOperand(rbx, JSGeneratorObject::kResumeModeOffset), rdx); |
| 585 |
| 586 // Load suspended function and context. |
| 587 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); |
| 588 __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); |
| 589 |
| 590 // Flood function if we are stepping. |
| 591 Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator; |
| 592 Label stepping_prepared; |
| 593 ExternalReference last_step_action = |
| 594 ExternalReference::debug_last_step_action_address(masm->isolate()); |
| 595 Operand last_step_action_operand = masm->ExternalOperand(last_step_action); |
| 596 STATIC_ASSERT(StepFrame > StepIn); |
| 597 __ cmpb(last_step_action_operand, Immediate(StepIn)); |
| 598 __ j(greater_equal, &prepare_step_in_if_stepping); |
| 599 |
| 600 // Flood function if we need to continue stepping in the suspended generator. |
| 601 ExternalReference debug_suspended_generator = |
| 602 ExternalReference::debug_suspended_generator_address(masm->isolate()); |
| 603 Operand debug_suspended_generator_operand = |
| 604 masm->ExternalOperand(debug_suspended_generator); |
| 605 __ cmpp(rbx, debug_suspended_generator_operand); |
| 606 __ j(equal, &prepare_step_in_suspended_generator); |
| 607 __ bind(&stepping_prepared); |
| 608 |
| 609 // Pop return address. |
| 610 __ PopReturnAddressTo(rax); |
| 611 |
| 612 // Push receiver. |
| 613 __ Push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); |
| 614 |
| 615 // ----------- S t a t e ------------- |
| 616 // -- rax : return address |
| 617 // -- rbx : the JSGeneratorObject to resume |
| 618 // -- rdx : the resume mode (tagged) |
| 619 // -- rdi : generator function |
| 620 // -- rsi : generator context |
| 621 // -- rsp[0] : generator receiver |
| 622 // ----------------------------------- |
| 623 |
| 624 // Push holes for arguments to generator function. Since the parser forced |
| 625 // context allocation for any variables in generators, the actual argument |
| 626 // values have already been copied into the context and these dummy values |
| 627 // will never be used. |
| 628 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 629 __ LoadSharedFunctionInfoSpecialField( |
| 630 rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset); |
| 631 { |
| 632 Label done_loop, loop; |
| 633 __ bind(&loop); |
| 634 __ subl(rcx, Immediate(1)); |
| 635 __ j(carry, &done_loop, Label::kNear); |
| 636 __ PushRoot(Heap::kTheHoleValueRootIndex); |
| 637 __ jmp(&loop); |
| 638 __ bind(&done_loop); |
| 639 } |
| 640 |
| 641 // Underlying function needs to have bytecode available. |
| 642 if (FLAG_debug_code) { |
| 643 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 644 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kFunctionDataOffset)); |
| 645 __ CmpObjectType(rcx, BYTECODE_ARRAY_TYPE, rcx); |
| 646 __ Assert(equal, kMissingBytecodeArray); |
| 647 } |
| 648 |
| 649 // Resume (Ignition/TurboFan) generator object. |
| 650 { |
| 651 __ PushReturnAddressFrom(rax); |
| 652 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 653 __ LoadSharedFunctionInfoSpecialField( |
| 654 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset); |
| 655 // We abuse new.target both to indicate that this is a resume call and to |
| 656 // pass in the generator object. In ordinary calls, new.target is always |
| 657 // undefined because generator functions are non-constructable. |
| 658 __ movp(rdx, rbx); |
| 659 __ jmp(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 660 } |
| 661 |
| 662 __ bind(&prepare_step_in_if_stepping); |
| 663 { |
| 664 FrameScope scope(masm, StackFrame::INTERNAL); |
| 665 __ Push(rbx); |
| 666 __ Push(rdx); |
| 667 __ Push(rdi); |
| 668 __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping); |
| 669 __ Pop(rdx); |
| 670 __ Pop(rbx); |
| 671 __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); |
| 672 } |
| 673 __ jmp(&stepping_prepared); |
| 674 |
| 675 __ bind(&prepare_step_in_suspended_generator); |
| 676 { |
| 677 FrameScope scope(masm, StackFrame::INTERNAL); |
| 678 __ Push(rbx); |
| 679 __ Push(rdx); |
| 680 __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator); |
| 681 __ Pop(rdx); |
| 682 __ Pop(rbx); |
| 683 __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); |
| 684 } |
| 685 __ jmp(&stepping_prepared); |
| 686 } |
| 687 |
562 static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1, | 688 static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1, |
563 Register scratch2) { | 689 Register scratch2) { |
564 Register args_count = scratch1; | 690 Register args_count = scratch1; |
565 Register return_pc = scratch2; | 691 Register return_pc = scratch2; |
566 | 692 |
567 // Get the arguments + receiver count. | 693 // Get the arguments + receiver count. |
568 __ movp(args_count, | 694 __ movp(args_count, |
569 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); | 695 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); |
570 __ movl(args_count, | 696 __ movl(args_count, |
571 FieldOperand(args_count, BytecodeArray::kParameterSizeOffset)); | 697 FieldOperand(args_count, BytecodeArray::kParameterSizeOffset)); |
(...skipping 2474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3046 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { | 3172 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
3047 Generate_OnStackReplacementHelper(masm, true); | 3173 Generate_OnStackReplacementHelper(masm, true); |
3048 } | 3174 } |
3049 | 3175 |
3050 #undef __ | 3176 #undef __ |
3051 | 3177 |
3052 } // namespace internal | 3178 } // namespace internal |
3053 } // namespace v8 | 3179 } // namespace v8 |
3054 | 3180 |
3055 #endif // V8_TARGET_ARCH_X64 | 3181 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |