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

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

Powered by Google App Engine
This is Rietveld 408576698