Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(799)

Side by Side Diff: src/x64/builtins-x64.cc

Issue 1986353002: Revert of [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.cc ('k') | test/unittests/interpreter/interpreter-assembler-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 __ Move( 692 __ Move(
693 kInterpreterDispatchTableRegister, 693 kInterpreterDispatchTableRegister,
694 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); 694 ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
695 695
696 // Dispatch to the first bytecode handler for the function. 696 // Dispatch to the first bytecode handler for the function.
697 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, 697 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister,
698 kInterpreterBytecodeOffsetRegister, times_1, 0)); 698 kInterpreterBytecodeOffsetRegister, times_1, 0));
699 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, 699 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx,
700 times_pointer_size, 0)); 700 times_pointer_size, 0));
701 __ call(rbx); 701 __ call(rbx);
702 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
703 702
704 // The return value is in rax. 703 // Even though the first bytecode handler was called, we will never return.
705 704 __ Abort(kUnexpectedReturnFromBytecodeHandler);
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);
718 705
719 // Load debug copy of the bytecode array. 706 // Load debug copy of the bytecode array.
720 __ bind(&load_debug_bytecode_array); 707 __ bind(&load_debug_bytecode_array);
721 Register debug_info = kInterpreterBytecodeArrayRegister; 708 Register debug_info = kInterpreterBytecodeArrayRegister;
722 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); 709 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset));
723 __ movp(kInterpreterBytecodeArrayRegister, 710 __ movp(kInterpreterBytecodeArrayRegister,
724 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); 711 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex));
725 __ jmp(&bytecode_array_loaded); 712 __ jmp(&bytecode_array_loaded);
726 713
727 // If the bytecode array is no longer present, then the underlying function 714 // 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 715 // 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. 716 // switching the code entry field over to the new code object as well.
730 __ bind(&bytecode_array_not_present); 717 __ bind(&bytecode_array_not_present);
731 __ leave(); // Leave the frame so we can tail call. 718 __ leave(); // Leave the frame so we can tail call.
732 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 719 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
733 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); 720 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset));
734 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 721 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
735 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); 722 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx);
736 __ RecordWriteCodeEntryField(rdi, rcx, r15); 723 __ RecordWriteCodeEntryField(rdi, rcx, r15);
737 __ jmp(rcx); 724 __ jmp(rcx);
738 } 725 }
739 726
727
728 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
729 // The return value is in accumulator, which is already in rax.
730
731 // Leave the frame (also dropping the register file).
732 __ leave();
733
734 // Drop receiver + arguments and return.
735 __ movl(rbx, FieldOperand(kInterpreterBytecodeArrayRegister,
736 BytecodeArray::kParameterSizeOffset));
737 __ PopReturnAddressTo(rcx);
738 __ addp(rsp, rbx);
739 __ PushReturnAddressFrom(rcx);
740 __ ret(0);
741 }
742
743
740 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 744 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
741 bool push_receiver) { 745 bool push_receiver) {
742 // ----------- S t a t e ------------- 746 // ----------- S t a t e -------------
743 // -- rax : the number of arguments (not including the receiver) 747 // -- rax : the number of arguments (not including the receiver)
744 // -- rbx : the address of the first argument to be pushed. Subsequent 748 // -- rbx : the address of the first argument to be pushed. Subsequent
745 // arguments should be consecutive above this, in the same order as 749 // arguments should be consecutive above this, in the same order as
746 // they are to be pushed onto the stack. 750 // they are to be pushed onto the stack.
747 // ----------------------------------- 751 // -----------------------------------
748 752
749 // Find the address of the last argument. 753 // Find the address of the last argument.
(...skipping 10 matching lines...) Expand all
760 Label loop_header, loop_check; 764 Label loop_header, loop_check;
761 __ j(always, &loop_check); 765 __ j(always, &loop_check);
762 __ bind(&loop_header); 766 __ bind(&loop_header);
763 __ Push(Operand(rbx, 0)); 767 __ Push(Operand(rbx, 0));
764 __ subp(rbx, Immediate(kPointerSize)); 768 __ subp(rbx, Immediate(kPointerSize));
765 __ bind(&loop_check); 769 __ bind(&loop_check);
766 __ cmpp(rbx, rcx); 770 __ cmpp(rbx, rcx);
767 __ j(greater, &loop_header, Label::kNear); 771 __ j(greater, &loop_header, Label::kNear);
768 } 772 }
769 773
774
770 // static 775 // static
771 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 776 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
772 MacroAssembler* masm, TailCallMode tail_call_mode) { 777 MacroAssembler* masm, TailCallMode tail_call_mode) {
773 // ----------- S t a t e ------------- 778 // ----------- S t a t e -------------
774 // -- rax : the number of arguments (not including the receiver) 779 // -- rax : the number of arguments (not including the receiver)
775 // -- rbx : the address of the first argument to be pushed. Subsequent 780 // -- rbx : the address of the first argument to be pushed. Subsequent
776 // arguments should be consecutive above this, in the same order as 781 // arguments should be consecutive above this, in the same order as
777 // they are to be pushed onto the stack. 782 // they are to be pushed onto the stack.
778 // -- rdi : the target to call (can be any Object). 783 // -- rdi : the target to call (can be any Object).
779 // ----------------------------------- 784 // -----------------------------------
780 785
781 // Pop return address to allow tail-call after pushing arguments. 786 // Pop return address to allow tail-call after pushing arguments.
782 __ PopReturnAddressTo(kScratchRegister); 787 __ PopReturnAddressTo(kScratchRegister);
783 788
784 Generate_InterpreterPushArgs(masm, true); 789 Generate_InterpreterPushArgs(masm, true);
785 790
786 // Call the target. 791 // Call the target.
787 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. 792 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
788 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 793 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
789 tail_call_mode), 794 tail_call_mode),
790 RelocInfo::CODE_TARGET); 795 RelocInfo::CODE_TARGET);
791 } 796 }
792 797
798
793 // static 799 // static
794 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { 800 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
795 // ----------- S t a t e ------------- 801 // ----------- S t a t e -------------
796 // -- rax : the number of arguments (not including the receiver) 802 // -- rax : the number of arguments (not including the receiver)
797 // -- rdx : the new target (either the same as the constructor or 803 // -- rdx : the new target (either the same as the constructor or
798 // the JSFunction on which new was invoked initially) 804 // the JSFunction on which new was invoked initially)
799 // -- rdi : the constructor to call (can be any Object) 805 // -- rdi : the constructor to call (can be any Object)
800 // -- rbx : the address of the first argument to be pushed. Subsequent 806 // -- rbx : the address of the first argument to be pushed. Subsequent
801 // arguments should be consecutive above this, in the same order as 807 // arguments should be consecutive above this, in the same order as
802 // they are to be pushed onto the stack. 808 // they are to be pushed onto the stack.
803 // ----------------------------------- 809 // -----------------------------------
804 810
805 // Pop return address to allow tail-call after pushing arguments. 811 // Pop return address to allow tail-call after pushing arguments.
806 __ PopReturnAddressTo(kScratchRegister); 812 __ PopReturnAddressTo(kScratchRegister);
807 813
808 // Push slot for the receiver to be constructed. 814 // Push slot for the receiver to be constructed.
809 __ Push(Immediate(0)); 815 __ Push(Immediate(0));
810 816
811 Generate_InterpreterPushArgs(masm, false); 817 Generate_InterpreterPushArgs(masm, false);
812 818
813 // Push return address in preparation for the tail-call. 819 // Push return address in preparation for the tail-call.
814 __ PushReturnAddressFrom(kScratchRegister); 820 __ PushReturnAddressFrom(kScratchRegister);
815 821
816 // Call the constructor (rax, rdx, rdi passed on). 822 // Call the constructor (rax, rdx, rdi passed on).
817 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 823 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
818 } 824 }
819 825
820 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
821 // Set the return address to the correct point in the interpreter entry
822 // trampoline.
823 Smi* interpreter_entry_return_pc_offset(
824 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
825 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
826 __ Move(rbx, masm->isolate()->builtins()->InterpreterEntryTrampoline());
827 __ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value() +
828 Code::kHeaderSize - kHeapObjectTag));
829 __ Push(rbx);
830 826
827 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
831 // Initialize dispatch table register. 828 // Initialize dispatch table register.
832 __ Move( 829 __ Move(
833 kInterpreterDispatchTableRegister, 830 kInterpreterDispatchTableRegister,
834 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); 831 ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
835 832
836 // Get the bytecode array pointer from the frame. 833 // Get the bytecode array pointer from the frame.
837 __ movp(kInterpreterBytecodeArrayRegister, 834 __ movp(kInterpreterBytecodeArrayRegister,
838 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); 835 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp));
839 836
840 if (FLAG_debug_code) { 837 if (FLAG_debug_code) {
(...skipping 11 matching lines...) Expand all
852 kInterpreterBytecodeOffsetRegister); 849 kInterpreterBytecodeOffsetRegister);
853 850
854 // Dispatch to the target bytecode. 851 // Dispatch to the target bytecode.
855 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, 852 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister,
856 kInterpreterBytecodeOffsetRegister, times_1, 0)); 853 kInterpreterBytecodeOffsetRegister, times_1, 0));
857 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, 854 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx,
858 times_pointer_size, 0)); 855 times_pointer_size, 0));
859 __ jmp(rbx); 856 __ jmp(rbx);
860 } 857 }
861 858
859
860 static void Generate_InterpreterNotifyDeoptimizedHelper(
861 MacroAssembler* masm, Deoptimizer::BailoutType type) {
862 // Enter an internal frame.
863 {
864 FrameScope scope(masm, StackFrame::INTERNAL);
865
866 // Pass the deoptimization type to the runtime system.
867 __ Push(Smi::FromInt(static_cast<int>(type)));
868 __ CallRuntime(Runtime::kNotifyDeoptimized);
869 // Tear down internal frame.
870 }
871
872 // Drop state (we don't use these for interpreter deopts) and and pop the
873 // accumulator value into the accumulator register and push PC at top
874 // of stack (to simulate initial call to bytecode handler in interpreter entry
875 // trampoline).
876 __ Pop(rbx);
877 __ Drop(1);
878 __ Pop(kInterpreterAccumulatorRegister);
879 __ Push(rbx);
880
881 // Enter the bytecode dispatch.
882 Generate_EnterBytecodeDispatch(masm);
883 }
884
885
886 void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
887 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
888 }
889
890
891 void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
892 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
893 }
894
895
896 void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
897 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
898 }
899
900 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
901 // Set the address of the interpreter entry trampoline as a return address.
902 // This simulates the initial call to bytecode handlers in interpreter entry
903 // trampoline. The return will never actually be taken, but our stack walker
904 // uses this address to determine whether a frame is interpreted.
905 __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline());
906
907 Generate_EnterBytecodeDispatch(masm);
908 }
909
910
862 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { 911 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
863 // ----------- S t a t e ------------- 912 // ----------- S t a t e -------------
864 // -- rax : argument count (preserved for callee) 913 // -- rax : argument count (preserved for callee)
865 // -- rdx : new target (preserved for callee) 914 // -- rdx : new target (preserved for callee)
866 // -- rdi : target function (preserved for callee) 915 // -- rdi : target function (preserved for callee)
867 // ----------------------------------- 916 // -----------------------------------
868 // First lookup code, maybe we don't need to compile! 917 // First lookup code, maybe we don't need to compile!
869 Label gotta_call_runtime; 918 Label gotta_call_runtime;
870 Label maybe_call_runtime; 919 Label maybe_call_runtime;
871 Label try_shared; 920 Label try_shared;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 1174
1126 __ CallRuntime(Runtime::kNotifyDeoptimized); 1175 __ CallRuntime(Runtime::kNotifyDeoptimized);
1127 // Tear down internal frame. 1176 // Tear down internal frame.
1128 } 1177 }
1129 1178
1130 // Get the full codegen state from the stack and untag it. 1179 // Get the full codegen state from the stack and untag it.
1131 __ SmiToInteger32(kScratchRegister, Operand(rsp, kPCOnStackSize)); 1180 __ SmiToInteger32(kScratchRegister, Operand(rsp, kPCOnStackSize));
1132 1181
1133 // Switch on the state. 1182 // Switch on the state.
1134 Label not_no_registers, not_tos_rax; 1183 Label not_no_registers, not_tos_rax;
1135 __ cmpp(kScratchRegister, 1184 __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::NO_REGISTERS));
1136 Immediate(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
1137 __ j(not_equal, &not_no_registers, Label::kNear); 1185 __ j(not_equal, &not_no_registers, Label::kNear);
1138 __ ret(1 * kPointerSize); // Remove state. 1186 __ ret(1 * kPointerSize); // Remove state.
1139 1187
1140 __ bind(&not_no_registers); 1188 __ bind(&not_no_registers);
1141 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), rax.code());
1142 __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize)); 1189 __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize));
1143 __ cmpp(kScratchRegister, 1190 __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::TOS_REG));
1144 Immediate(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
1145 __ j(not_equal, &not_tos_rax, Label::kNear); 1191 __ j(not_equal, &not_tos_rax, Label::kNear);
1146 __ ret(2 * kPointerSize); // Remove state, rax. 1192 __ ret(2 * kPointerSize); // Remove state, rax.
1147 1193
1148 __ bind(&not_tos_rax); 1194 __ bind(&not_tos_rax);
1149 __ Abort(kNoCasesLeft); 1195 __ Abort(kNoCasesLeft);
1150 } 1196 }
1151 1197
1152 1198
1153 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { 1199 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1154 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); 1200 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 __ ret(0); 2955 __ ret(0);
2910 } 2956 }
2911 2957
2912 2958
2913 #undef __ 2959 #undef __
2914 2960
2915 } // namespace internal 2961 } // namespace internal
2916 } // namespace v8 2962 } // namespace v8
2917 2963
2918 #endif // V8_TARGET_ARCH_X64 2964 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | test/unittests/interpreter/interpreter-assembler-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698