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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 __ SmiToInteger64( | 591 __ SmiToInteger64( |
592 rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); | 592 rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); |
593 __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); | 593 __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); |
594 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), | 594 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), |
595 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); | 595 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); |
596 __ movp(rax, rbx); // Continuation expects generator object in rax. | 596 __ movp(rax, rbx); // Continuation expects generator object in rax. |
597 __ jmp(rdx); | 597 __ jmp(rdx); |
598 } | 598 } |
599 } | 599 } |
600 | 600 |
| 601 static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1, |
| 602 Register scratch2) { |
| 603 Register args_count = scratch1; |
| 604 Register return_pc = scratch2; |
| 605 |
| 606 // Get the arguments + receiver count. |
| 607 __ movp(args_count, |
| 608 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); |
| 609 __ movl(args_count, |
| 610 FieldOperand(args_count, BytecodeArray::kParameterSizeOffset)); |
| 611 |
| 612 // Leave the frame (also dropping the register file). |
| 613 __ leave(); |
| 614 |
| 615 // Drop receiver + arguments. |
| 616 __ PopReturnAddressTo(return_pc); |
| 617 __ addp(rsp, args_count); |
| 618 __ PushReturnAddressFrom(return_pc); |
| 619 } |
| 620 |
601 // Generate code for entering a JS function with the interpreter. | 621 // Generate code for entering a JS function with the interpreter. |
602 // On entry to the function the receiver and arguments have been pushed on the | 622 // On entry to the function the receiver and arguments have been pushed on the |
603 // stack left to right. The actual argument count matches the formal parameter | 623 // stack left to right. The actual argument count matches the formal parameter |
604 // count expected by the function. | 624 // count expected by the function. |
605 // | 625 // |
606 // The live registers are: | 626 // The live registers are: |
607 // o rdi: the JS function object being called | 627 // o rdi: the JS function object being called |
608 // o rdx: the new target | 628 // o rdx: the new target |
609 // o rsi: our context | 629 // o rsi: our context |
610 // o rbp: the caller's frame pointer | 630 // o rbp: the caller's frame pointer |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 | 715 |
696 // Dispatch to the first bytecode handler for the function. | 716 // Dispatch to the first bytecode handler for the function. |
697 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, | 717 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, |
698 kInterpreterBytecodeOffsetRegister, times_1, 0)); | 718 kInterpreterBytecodeOffsetRegister, times_1, 0)); |
699 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, | 719 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, |
700 times_pointer_size, 0)); | 720 times_pointer_size, 0)); |
701 __ call(rbx); | 721 __ call(rbx); |
702 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); | 722 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); |
703 | 723 |
704 // The return value is in rax. | 724 // The return value is in rax. |
705 | 725 LeaveInterpreterFrame(masm, rbx, rcx); |
706 // Get the arguments + reciever count. | |
707 __ movp(rbx, Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); | |
708 __ movl(rbx, FieldOperand(rbx, BytecodeArray::kParameterSizeOffset)); | |
709 | |
710 // Leave the frame (also dropping the register file). | |
711 __ leave(); | |
712 | |
713 // Drop receiver + arguments and return. | |
714 __ PopReturnAddressTo(rcx); | |
715 __ addp(rsp, rbx); | |
716 __ PushReturnAddressFrom(rcx); | |
717 __ ret(0); | 726 __ ret(0); |
718 | 727 |
719 // Load debug copy of the bytecode array. | 728 // Load debug copy of the bytecode array. |
720 __ bind(&load_debug_bytecode_array); | 729 __ bind(&load_debug_bytecode_array); |
721 Register debug_info = kInterpreterBytecodeArrayRegister; | 730 Register debug_info = kInterpreterBytecodeArrayRegister; |
722 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); | 731 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); |
723 __ movp(kInterpreterBytecodeArrayRegister, | 732 __ movp(kInterpreterBytecodeArrayRegister, |
724 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); | 733 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
725 __ jmp(&bytecode_array_loaded); | 734 __ jmp(&bytecode_array_loaded); |
726 | 735 |
727 // If the bytecode array is no longer present, then the underlying function | 736 // If the bytecode array is no longer present, then the underlying function |
728 // has been switched to a different kind of code and we heal the closure by | 737 // has been switched to a different kind of code and we heal the closure by |
729 // switching the code entry field over to the new code object as well. | 738 // switching the code entry field over to the new code object as well. |
730 __ bind(&bytecode_array_not_present); | 739 __ bind(&bytecode_array_not_present); |
731 __ leave(); // Leave the frame so we can tail call. | 740 __ leave(); // Leave the frame so we can tail call. |
732 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 741 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
733 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); | 742 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); |
734 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 743 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
735 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); | 744 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); |
736 __ RecordWriteCodeEntryField(rdi, rcx, r15); | 745 __ RecordWriteCodeEntryField(rdi, rcx, r15); |
737 __ jmp(rcx); | 746 __ jmp(rcx); |
738 } | 747 } |
739 | 748 |
| 749 void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) { |
| 750 // Save the function and context for call to CompileBaseline. |
| 751 __ movp(rdi, Operand(rbp, StandardFrameConstants::kFunctionOffset)); |
| 752 __ movp(kContextRegister, |
| 753 Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 754 |
| 755 // Leave the frame before recompiling for baseline so that we don't count as |
| 756 // an activation on the stack. |
| 757 LeaveInterpreterFrame(masm, rbx, rcx); |
| 758 |
| 759 { |
| 760 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 761 // Push return value. |
| 762 __ Push(rax); |
| 763 |
| 764 // Push function as argument and compile for baseline. |
| 765 __ Push(rdi); |
| 766 __ CallRuntime(Runtime::kCompileBaseline); |
| 767 |
| 768 // Restore return value. |
| 769 __ Pop(rax); |
| 770 } |
| 771 __ ret(0); |
| 772 } |
| 773 |
740 static void Generate_InterpreterPushArgs(MacroAssembler* masm, | 774 static void Generate_InterpreterPushArgs(MacroAssembler* masm, |
741 bool push_receiver) { | 775 bool push_receiver) { |
742 // ----------- S t a t e ------------- | 776 // ----------- S t a t e ------------- |
743 // -- rax : the number of arguments (not including the receiver) | 777 // -- rax : the number of arguments (not including the receiver) |
744 // -- rbx : the address of the first argument to be pushed. Subsequent | 778 // -- rbx : the address of the first argument to be pushed. Subsequent |
745 // arguments should be consecutive above this, in the same order as | 779 // arguments should be consecutive above this, in the same order as |
746 // they are to be pushed onto the stack. | 780 // they are to be pushed onto the stack. |
747 // ----------------------------------- | 781 // ----------------------------------- |
748 | 782 |
749 // Find the address of the last argument. | 783 // Find the address of the last argument. |
(...skipping 2136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 __ ret(0); | 2920 __ ret(0); |
2887 } | 2921 } |
2888 | 2922 |
2889 | 2923 |
2890 #undef __ | 2924 #undef __ |
2891 | 2925 |
2892 } // namespace internal | 2926 } // namespace internal |
2893 } // namespace v8 | 2927 } // namespace v8 |
2894 | 2928 |
2895 #endif // V8_TARGET_ARCH_X64 | 2929 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |