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

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

Issue 1987053006: X87: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampol… (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/full-codegen/x87/full-codegen-x87.cc ('k') | no next file » | 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_X87 5 #if V8_TARGET_ARCH_X87
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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 __ mov(kInterpreterDispatchTableRegister, 614 __ mov(kInterpreterDispatchTableRegister,
615 Immediate(ExternalReference::interpreter_dispatch_table_address( 615 Immediate(ExternalReference::interpreter_dispatch_table_address(
616 masm->isolate()))); 616 masm->isolate())));
617 617
618 // Dispatch to the first bytecode handler for the function. 618 // Dispatch to the first bytecode handler for the function.
619 __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister, 619 __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
620 kInterpreterBytecodeOffsetRegister, times_1, 0)); 620 kInterpreterBytecodeOffsetRegister, times_1, 0));
621 __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx, 621 __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
622 times_pointer_size, 0)); 622 times_pointer_size, 0));
623 __ call(ebx); 623 __ call(ebx);
624 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
624 625
625 // Even though the first bytecode handler was called, we will never return. 626 // The return value is in eax.
626 __ Abort(kUnexpectedReturnFromBytecodeHandler); 627
628 // Get the arguments + reciever count.
629 __ mov(ebx, Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
630 __ mov(ebx, FieldOperand(ebx, BytecodeArray::kParameterSizeOffset));
631
632 // Leave the frame (also dropping the register file).
633 __ leave();
634
635 // Drop receiver + arguments and return.
636 __ pop(ecx);
637 __ add(esp, ebx);
638 __ push(ecx);
639 __ ret(0);
627 640
628 // Load debug copy of the bytecode array. 641 // Load debug copy of the bytecode array.
629 __ bind(&load_debug_bytecode_array); 642 __ bind(&load_debug_bytecode_array);
630 Register debug_info = kInterpreterBytecodeArrayRegister; 643 Register debug_info = kInterpreterBytecodeArrayRegister;
631 __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset)); 644 __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset));
632 __ mov(kInterpreterBytecodeArrayRegister, 645 __ mov(kInterpreterBytecodeArrayRegister,
633 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); 646 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex));
634 __ jmp(&bytecode_array_loaded); 647 __ jmp(&bytecode_array_loaded);
635 648
636 // If the bytecode array is no longer present, then the underlying function 649 // If the bytecode array is no longer present, then the underlying function
637 // has been switched to a different kind of code and we heal the closure by 650 // has been switched to a different kind of code and we heal the closure by
638 // switching the code entry field over to the new code object as well. 651 // switching the code entry field over to the new code object as well.
639 __ bind(&bytecode_array_not_present); 652 __ bind(&bytecode_array_not_present);
640 __ pop(edx); // Callee's new target. 653 __ pop(edx); // Callee's new target.
641 __ pop(edi); // Callee's JS function. 654 __ pop(edi); // Callee's JS function.
642 __ pop(esi); // Callee's context. 655 __ pop(esi); // Callee's context.
643 __ leave(); // Leave the frame so we can tail call. 656 __ leave(); // Leave the frame so we can tail call.
644 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 657 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
645 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset)); 658 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset));
646 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); 659 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
647 __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx); 660 __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx);
648 __ RecordWriteCodeEntryField(edi, ecx, ebx); 661 __ RecordWriteCodeEntryField(edi, ecx, ebx);
649 __ jmp(ecx); 662 __ jmp(ecx);
650 } 663 }
651 664
652
653 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
654 // Interpreter handler is turbofanned code, need to reset the FPU before
655 // return
656 __ fninit();
657
658 // The return value is in accumulator, which is already in eax.
659
660 // Leave the frame (also dropping the register file).
661 __ leave();
662
663 // Drop receiver + arguments and return.
664 __ mov(ebx, FieldOperand(kInterpreterBytecodeArrayRegister,
665 BytecodeArray::kParameterSizeOffset));
666 __ pop(ecx);
667 __ add(esp, ebx);
668 __ push(ecx);
669 __ ret(0);
670 }
671
672
673 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 665 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
674 Register array_limit) { 666 Register array_limit) {
675 // ----------- S t a t e ------------- 667 // ----------- S t a t e -------------
676 // -- ebx : Pointer to the last argument in the args array. 668 // -- ebx : Pointer to the last argument in the args array.
677 // -- array_limit : Pointer to one before the first argument in the 669 // -- array_limit : Pointer to one before the first argument in the
678 // args array. 670 // args array.
679 // ----------------------------------- 671 // -----------------------------------
680 Label loop_header, loop_check; 672 Label loop_header, loop_check;
681 __ jmp(&loop_check); 673 __ jmp(&loop_check);
682 __ bind(&loop_header); 674 __ bind(&loop_header);
683 __ Push(Operand(ebx, 0)); 675 __ Push(Operand(ebx, 0));
684 __ sub(ebx, Immediate(kPointerSize)); 676 __ sub(ebx, Immediate(kPointerSize));
685 __ bind(&loop_check); 677 __ bind(&loop_check);
686 __ cmp(ebx, array_limit); 678 __ cmp(ebx, array_limit);
687 __ j(greater, &loop_header, Label::kNear); 679 __ j(greater, &loop_header, Label::kNear);
688 } 680 }
689 681
690
691 // static 682 // static
692 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 683 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
693 MacroAssembler* masm, TailCallMode tail_call_mode) { 684 MacroAssembler* masm, TailCallMode tail_call_mode) {
694 // ----------- S t a t e ------------- 685 // ----------- S t a t e -------------
695 // -- eax : the number of arguments (not including the receiver) 686 // -- eax : the number of arguments (not including the receiver)
696 // -- ebx : the address of the first argument to be pushed. Subsequent 687 // -- ebx : the address of the first argument to be pushed. Subsequent
697 // arguments should be consecutive above this, in the same order as 688 // arguments should be consecutive above this, in the same order as
698 // they are to be pushed onto the stack. 689 // they are to be pushed onto the stack.
699 // -- edi : the target to call (can be any Object). 690 // -- edi : the target to call (can be any Object).
700 // ----------------------------------- 691 // -----------------------------------
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // meant for receiver. 740 // meant for receiver.
750 __ mov(edi, Operand(esp, eax, times_pointer_size, 0)); 741 __ mov(edi, Operand(esp, eax, times_pointer_size, 0));
751 742
752 // Re-push return address. 743 // Re-push return address.
753 __ Push(ecx); 744 __ Push(ecx);
754 745
755 // Call the constructor with unmodified eax, edi, ebi values. 746 // Call the constructor with unmodified eax, edi, ebi values.
756 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 747 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
757 } 748 }
758 749
750 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
751 // Set the return address to the correct point in the interpreter entry
752 // trampoline.
753 Smi* interpreter_entry_return_pc_offset(
754 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
755 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
756 __ LoadHeapObject(ebx,
757 masm->isolate()->builtins()->InterpreterEntryTrampoline());
758 __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() +
759 Code::kHeaderSize - kHeapObjectTag));
760 __ push(ebx);
759 761
760 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
761 // Initialize the dispatch table register. 762 // Initialize the dispatch table register.
762 __ mov(kInterpreterDispatchTableRegister, 763 __ mov(kInterpreterDispatchTableRegister,
763 Immediate(ExternalReference::interpreter_dispatch_table_address( 764 Immediate(ExternalReference::interpreter_dispatch_table_address(
764 masm->isolate()))); 765 masm->isolate())));
765 766
766 // Get the bytecode array pointer from the frame. 767 // Get the bytecode array pointer from the frame.
767 __ mov(kInterpreterBytecodeArrayRegister, 768 __ mov(kInterpreterBytecodeArrayRegister,
768 Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp)); 769 Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
769 770
770 if (FLAG_debug_code) { 771 if (FLAG_debug_code) {
(...skipping 10 matching lines...) Expand all
781 __ SmiUntag(kInterpreterBytecodeOffsetRegister); 782 __ SmiUntag(kInterpreterBytecodeOffsetRegister);
782 783
783 // Dispatch to the target bytecode. 784 // Dispatch to the target bytecode.
784 __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister, 785 __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
785 kInterpreterBytecodeOffsetRegister, times_1, 0)); 786 kInterpreterBytecodeOffsetRegister, times_1, 0));
786 __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx, 787 __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
787 times_pointer_size, 0)); 788 times_pointer_size, 0));
788 __ jmp(ebx); 789 __ jmp(ebx);
789 } 790 }
790 791
791
792 static void Generate_InterpreterNotifyDeoptimizedHelper(
793 MacroAssembler* masm, Deoptimizer::BailoutType type) {
794 // Enter an internal frame.
795 {
796 FrameScope scope(masm, StackFrame::INTERNAL);
797
798 // Pass the deoptimization type to the runtime system.
799 __ Push(Smi::FromInt(static_cast<int>(type)));
800 __ CallRuntime(Runtime::kNotifyDeoptimized);
801 // Tear down internal frame.
802 }
803
804 // Drop state (we don't use these for interpreter deopts) and and pop the
805 // accumulator value into the accumulator register and push PC at top
806 // of stack (to simulate initial call to bytecode handler in interpreter entry
807 // trampoline).
808 __ Pop(ebx);
809 __ Drop(1);
810 __ Pop(kInterpreterAccumulatorRegister);
811 __ Push(ebx);
812
813 // Enter the bytecode dispatch.
814 Generate_EnterBytecodeDispatch(masm);
815 }
816
817
818 void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
819 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
820 }
821
822
823 void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
824 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
825 }
826
827
828 void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
829 Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
830 }
831
832 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
833 // Set the address of the interpreter entry trampoline as a return address.
834 // This simulates the initial call to bytecode handlers in interpreter entry
835 // trampoline. The return will never actually be taken, but our stack walker
836 // uses this address to determine whether a frame is interpreted.
837 __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline());
838
839 Generate_EnterBytecodeDispatch(masm);
840 }
841
842
843 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { 792 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
844 // ----------- S t a t e ------------- 793 // ----------- S t a t e -------------
845 // -- eax : argument count (preserved for callee) 794 // -- eax : argument count (preserved for callee)
846 // -- edx : new target (preserved for callee) 795 // -- edx : new target (preserved for callee)
847 // -- edi : target function (preserved for callee) 796 // -- edi : target function (preserved for callee)
848 // ----------------------------------- 797 // -----------------------------------
849 // First lookup code, maybe we don't need to compile! 798 // First lookup code, maybe we don't need to compile!
850 Label gotta_call_runtime, gotta_call_runtime_no_stack; 799 Label gotta_call_runtime, gotta_call_runtime_no_stack;
851 Label maybe_call_runtime; 800 Label maybe_call_runtime;
852 Label try_shared; 801 Label try_shared;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 1078
1130 // Tear down internal frame. 1079 // Tear down internal frame.
1131 } 1080 }
1132 1081
1133 // Get the full codegen state from the stack and untag it. 1082 // Get the full codegen state from the stack and untag it.
1134 __ mov(ecx, Operand(esp, 1 * kPointerSize)); 1083 __ mov(ecx, Operand(esp, 1 * kPointerSize));
1135 __ SmiUntag(ecx); 1084 __ SmiUntag(ecx);
1136 1085
1137 // Switch on the state. 1086 // Switch on the state.
1138 Label not_no_registers, not_tos_eax; 1087 Label not_no_registers, not_tos_eax;
1139 __ cmp(ecx, FullCodeGenerator::NO_REGISTERS); 1088 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS));
1140 __ j(not_equal, &not_no_registers, Label::kNear); 1089 __ j(not_equal, &not_no_registers, Label::kNear);
1141 __ ret(1 * kPointerSize); // Remove state. 1090 __ ret(1 * kPointerSize); // Remove state.
1142 1091
1143 __ bind(&not_no_registers); 1092 __ bind(&not_no_registers);
1093 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code());
1144 __ mov(eax, Operand(esp, 2 * kPointerSize)); 1094 __ mov(eax, Operand(esp, 2 * kPointerSize));
1145 __ cmp(ecx, FullCodeGenerator::TOS_REG); 1095 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER));
1146 __ j(not_equal, &not_tos_eax, Label::kNear); 1096 __ j(not_equal, &not_tos_eax, Label::kNear);
1147 __ ret(2 * kPointerSize); // Remove state, eax. 1097 __ ret(2 * kPointerSize); // Remove state, eax.
1148 1098
1149 __ bind(&not_tos_eax); 1099 __ bind(&not_tos_eax);
1150 __ Abort(kNoCasesLeft); 1100 __ Abort(kNoCasesLeft);
1151 } 1101 }
1152 1102
1153 1103
1154 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { 1104 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1155 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); 1105 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
(...skipping 1747 matching lines...) Expand 10 before | Expand all | Expand 10 after
2903 // And "return" to the OSR entry point of the function. 2853 // And "return" to the OSR entry point of the function.
2904 __ ret(0); 2854 __ ret(0);
2905 } 2855 }
2906 2856
2907 2857
2908 #undef __ 2858 #undef __
2909 } // namespace internal 2859 } // namespace internal
2910 } // namespace v8 2860 } // namespace v8
2911 2861
2912 #endif // V8_TARGET_ARCH_X87 2862 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698