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

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

Issue 1969423002: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review comments 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());
702 703
703 // Even though the first bytecode handler was called, we will never return. 704 // The return value is in rax.
704 __ Abort(kUnexpectedReturnFromBytecodeHandler); 705
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);
705 718
706 // Load debug copy of the bytecode array. 719 // Load debug copy of the bytecode array.
707 __ bind(&load_debug_bytecode_array); 720 __ bind(&load_debug_bytecode_array);
708 Register debug_info = kInterpreterBytecodeArrayRegister; 721 Register debug_info = kInterpreterBytecodeArrayRegister;
709 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); 722 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset));
710 __ movp(kInterpreterBytecodeArrayRegister, 723 __ movp(kInterpreterBytecodeArrayRegister,
711 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); 724 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex));
712 __ jmp(&bytecode_array_loaded); 725 __ jmp(&bytecode_array_loaded);
713 726
714 // If the bytecode array is no longer present, then the underlying function 727 // If the bytecode array is no longer present, then the underlying function
715 // has been switched to a different kind of code and we heal the closure by 728 // has been switched to a different kind of code and we heal the closure by
716 // switching the code entry field over to the new code object as well. 729 // switching the code entry field over to the new code object as well.
717 __ bind(&bytecode_array_not_present); 730 __ bind(&bytecode_array_not_present);
718 __ leave(); // Leave the frame so we can tail call. 731 __ leave(); // Leave the frame so we can tail call.
719 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 732 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
720 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); 733 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset));
721 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 734 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
722 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); 735 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx);
723 __ RecordWriteCodeEntryField(rdi, rcx, r15); 736 __ RecordWriteCodeEntryField(rdi, rcx, r15);
724 __ jmp(rcx); 737 __ jmp(rcx);
725 } 738 }
726 739
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
744 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 740 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
745 bool push_receiver) { 741 bool push_receiver) {
746 // ----------- S t a t e ------------- 742 // ----------- S t a t e -------------
747 // -- rax : the number of arguments (not including the receiver) 743 // -- rax : the number of arguments (not including the receiver)
748 // -- rbx : the address of the first argument to be pushed. Subsequent 744 // -- rbx : the address of the first argument to be pushed. Subsequent
749 // arguments should be consecutive above this, in the same order as 745 // arguments should be consecutive above this, in the same order as
750 // they are to be pushed onto the stack. 746 // they are to be pushed onto the stack.
751 // ----------------------------------- 747 // -----------------------------------
752 748
753 // Find the address of the last argument. 749 // Find the address of the last argument.
(...skipping 10 matching lines...) Expand all
764 Label loop_header, loop_check; 760 Label loop_header, loop_check;
765 __ j(always, &loop_check); 761 __ j(always, &loop_check);
766 __ bind(&loop_header); 762 __ bind(&loop_header);
767 __ Push(Operand(rbx, 0)); 763 __ Push(Operand(rbx, 0));
768 __ subp(rbx, Immediate(kPointerSize)); 764 __ subp(rbx, Immediate(kPointerSize));
769 __ bind(&loop_check); 765 __ bind(&loop_check);
770 __ cmpp(rbx, rcx); 766 __ cmpp(rbx, rcx);
771 __ j(greater, &loop_header, Label::kNear); 767 __ j(greater, &loop_header, Label::kNear);
772 } 768 }
773 769
774
775 // static 770 // static
776 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 771 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
777 MacroAssembler* masm, TailCallMode tail_call_mode) { 772 MacroAssembler* masm, TailCallMode tail_call_mode) {
778 // ----------- S t a t e ------------- 773 // ----------- S t a t e -------------
779 // -- rax : the number of arguments (not including the receiver) 774 // -- rax : the number of arguments (not including the receiver)
780 // -- rbx : the address of the first argument to be pushed. Subsequent 775 // -- rbx : the address of the first argument to be pushed. Subsequent
781 // arguments should be consecutive above this, in the same order as 776 // arguments should be consecutive above this, in the same order as
782 // they are to be pushed onto the stack. 777 // they are to be pushed onto the stack.
783 // -- rdi : the target to call (can be any Object). 778 // -- rdi : the target to call (can be any Object).
784 // ----------------------------------- 779 // -----------------------------------
785 780
786 // Pop return address to allow tail-call after pushing arguments. 781 // Pop return address to allow tail-call after pushing arguments.
787 __ PopReturnAddressTo(kScratchRegister); 782 __ PopReturnAddressTo(kScratchRegister);
788 783
789 Generate_InterpreterPushArgs(masm, true); 784 Generate_InterpreterPushArgs(masm, true);
790 785
791 // Call the target. 786 // Call the target.
792 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. 787 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
793 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 788 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
794 tail_call_mode), 789 tail_call_mode),
795 RelocInfo::CODE_TARGET); 790 RelocInfo::CODE_TARGET);
796 } 791 }
797 792
798
799 // static 793 // static
800 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { 794 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
801 // ----------- S t a t e ------------- 795 // ----------- S t a t e -------------
802 // -- rax : the number of arguments (not including the receiver) 796 // -- rax : the number of arguments (not including the receiver)
803 // -- rdx : the new target (either the same as the constructor or 797 // -- rdx : the new target (either the same as the constructor or
804 // the JSFunction on which new was invoked initially) 798 // the JSFunction on which new was invoked initially)
805 // -- rdi : the constructor to call (can be any Object) 799 // -- rdi : the constructor to call (can be any Object)
806 // -- rbx : the address of the first argument to be pushed. Subsequent 800 // -- rbx : the address of the first argument to be pushed. Subsequent
807 // arguments should be consecutive above this, in the same order as 801 // arguments should be consecutive above this, in the same order as
808 // they are to be pushed onto the stack. 802 // they are to be pushed onto the stack.
809 // ----------------------------------- 803 // -----------------------------------
810 804
811 // Pop return address to allow tail-call after pushing arguments. 805 // Pop return address to allow tail-call after pushing arguments.
812 __ PopReturnAddressTo(kScratchRegister); 806 __ PopReturnAddressTo(kScratchRegister);
813 807
814 // Push slot for the receiver to be constructed. 808 // Push slot for the receiver to be constructed.
815 __ Push(Immediate(0)); 809 __ Push(Immediate(0));
816 810
817 Generate_InterpreterPushArgs(masm, false); 811 Generate_InterpreterPushArgs(masm, false);
818 812
819 // Push return address in preparation for the tail-call. 813 // Push return address in preparation for the tail-call.
820 __ PushReturnAddressFrom(kScratchRegister); 814 __ PushReturnAddressFrom(kScratchRegister);
821 815
822 // Call the constructor (rax, rdx, rdi passed on). 816 // Call the constructor (rax, rdx, rdi passed on).
823 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 817 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
824 } 818 }
825 819
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);
826 830
827 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
828 // Initialize dispatch table register. 831 // Initialize dispatch table register.
829 __ Move( 832 __ Move(
830 kInterpreterDispatchTableRegister, 833 kInterpreterDispatchTableRegister,
831 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); 834 ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
832 835
833 // Get the bytecode array pointer from the frame. 836 // Get the bytecode array pointer from the frame.
834 __ movp(kInterpreterBytecodeArrayRegister, 837 __ movp(kInterpreterBytecodeArrayRegister,
835 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); 838 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp));
836 839
837 if (FLAG_debug_code) { 840 if (FLAG_debug_code) {
(...skipping 11 matching lines...) Expand all
849 kInterpreterBytecodeOffsetRegister); 852 kInterpreterBytecodeOffsetRegister);
850 853
851 // Dispatch to the target bytecode. 854 // Dispatch to the target bytecode.
852 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, 855 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister,
853 kInterpreterBytecodeOffsetRegister, times_1, 0)); 856 kInterpreterBytecodeOffsetRegister, times_1, 0));
854 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, 857 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx,
855 times_pointer_size, 0)); 858 times_pointer_size, 0));
856 __ jmp(rbx); 859 __ jmp(rbx);
857 } 860 }
858 861
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
911 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { 862 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
912 // ----------- S t a t e ------------- 863 // ----------- S t a t e -------------
913 // -- rax : argument count (preserved for callee) 864 // -- rax : argument count (preserved for callee)
914 // -- rdx : new target (preserved for callee) 865 // -- rdx : new target (preserved for callee)
915 // -- rdi : target function (preserved for callee) 866 // -- rdi : target function (preserved for callee)
916 // ----------------------------------- 867 // -----------------------------------
917 // First lookup code, maybe we don't need to compile! 868 // First lookup code, maybe we don't need to compile!
918 Label gotta_call_runtime; 869 Label gotta_call_runtime;
919 Label maybe_call_runtime; 870 Label maybe_call_runtime;
920 Label try_shared; 871 Label try_shared;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 1125
1175 __ CallRuntime(Runtime::kNotifyDeoptimized); 1126 __ CallRuntime(Runtime::kNotifyDeoptimized);
1176 // Tear down internal frame. 1127 // Tear down internal frame.
1177 } 1128 }
1178 1129
1179 // Get the full codegen state from the stack and untag it. 1130 // Get the full codegen state from the stack and untag it.
1180 __ SmiToInteger32(kScratchRegister, Operand(rsp, kPCOnStackSize)); 1131 __ SmiToInteger32(kScratchRegister, Operand(rsp, kPCOnStackSize));
1181 1132
1182 // Switch on the state. 1133 // Switch on the state.
1183 Label not_no_registers, not_tos_rax; 1134 Label not_no_registers, not_tos_rax;
1184 __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::NO_REGISTERS)); 1135 __ cmpp(kScratchRegister,
1136 Immediate(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
1185 __ j(not_equal, &not_no_registers, Label::kNear); 1137 __ j(not_equal, &not_no_registers, Label::kNear);
1186 __ ret(1 * kPointerSize); // Remove state. 1138 __ ret(1 * kPointerSize); // Remove state.
1187 1139
1188 __ bind(&not_no_registers); 1140 __ bind(&not_no_registers);
1141 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), rax.code());
1189 __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize)); 1142 __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize));
1190 __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::TOS_REG)); 1143 __ cmpp(kScratchRegister,
1144 Immediate(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
1191 __ j(not_equal, &not_tos_rax, Label::kNear); 1145 __ j(not_equal, &not_tos_rax, Label::kNear);
1192 __ ret(2 * kPointerSize); // Remove state, rax. 1146 __ ret(2 * kPointerSize); // Remove state, rax.
1193 1147
1194 __ bind(&not_tos_rax); 1148 __ bind(&not_tos_rax);
1195 __ Abort(kNoCasesLeft); 1149 __ Abort(kNoCasesLeft);
1196 } 1150 }
1197 1151
1198 1152
1199 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { 1153 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1200 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); 1154 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 __ ret(0); 2909 __ ret(0);
2956 } 2910 }
2957 2911
2958 2912
2959 #undef __ 2913 #undef __
2960 2914
2961 } // namespace internal 2915 } // namespace internal
2962 } // namespace v8 2916 } // namespace v8
2963 2917
2964 #endif // V8_TARGET_ARCH_X64 2918 #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