Chromium Code Reviews| 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 | |
|
Dan Ehrenberg
2017/01/13 19:41:09
Presumably this would only be called on JSAsyncGen
caitp
2017/01/13 20:11:52
Yes, will update the comment. I don't think it's w
| |
| 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); | |
|
Dan Ehrenberg
2017/01/13 19:41:09
Is the only difference here vs Generate_ResumeGene
caitp
2017/01/13 20:11:52
I agree :D but... I kind of want to avoid adding a
| |
| 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 |