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_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 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
754 tail_call_mode), | 754 tail_call_mode), |
755 RelocInfo::CODE_TARGET); | 755 RelocInfo::CODE_TARGET); |
756 } else { | 756 } else { |
757 DCHECK_EQ(function_type, CallableType::kAny); | 757 DCHECK_EQ(function_type, CallableType::kAny); |
758 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 758 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
759 tail_call_mode), | 759 tail_call_mode), |
760 RelocInfo::CODE_TARGET); | 760 RelocInfo::CODE_TARGET); |
761 } | 761 } |
762 } | 762 } |
763 | 763 |
764 // static | 764 namespace { |
765 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( | |
766 MacroAssembler* masm, CallableType construct_type) { | |
767 // ----------- S t a t e ------------- | |
768 // -- eax : the number of arguments (not including the receiver) | |
769 // -- edx : the new target | |
770 // -- edi : the constructor | |
771 // -- ebx : allocation site feedback (if available or undefined) | |
772 // -- ecx : the address of the first argument to be pushed. Subsequent | |
773 // arguments should be consecutive above this, in the same order as | |
774 // they are to be pushed onto the stack. | |
775 // ----------------------------------- | |
776 | 765 |
766 // Does not assume any free registers. Maintains all registers in their | |
767 // original state on return. | |
768 void Generate_InterpreterPushArgsAndReturnAddress(MacroAssembler* masm, | |
769 bool is_receiver_available) { | |
rmcilroy
2016/09/06 10:59:35
Could you pass the registers which are used as arg
mythria
2016/09/07 08:59:44
Done.
| |
777 // Store edi, edx onto the stack. We need two extra registers | 770 // Store edi, edx onto the stack. We need two extra registers |
778 // so store edi, edx temporarily on stack. | 771 // so store edi, edx temporarily on stack. |
779 __ Push(edi); | 772 __ Push(edi); |
780 __ Push(edx); | 773 __ Push(edx); |
781 | 774 |
782 // We have to pop return address and the two temporary registers before we | 775 // We have to pop return address and the two temporary registers before we |
783 // can push arguments onto the stack. we do not have any free registers so | 776 // can push arguments onto the stack. we do not have any free registers so |
784 // update the stack and copy them into the correct places on the stack. | 777 // update the stack and copy them into the correct places on the stack. |
785 // current stack =====> required stack layout | 778 // current stack =====> required stack layout |
786 // | | | edx | (2) <-- esp(1) | 779 // | | | edx | (2) <-- esp(1) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
830 __ mov(Operand(esp, 0), edi); | 823 __ mov(Operand(esp, 0), edi); |
831 | 824 |
832 // Step 3 move edi to the correct location | 825 // Step 3 move edi to the correct location |
833 __ mov(edi, Operand(esp, eax, times_pointer_size, 2 * kPointerSize)); | 826 __ mov(edi, Operand(esp, eax, times_pointer_size, 2 * kPointerSize)); |
834 __ mov(Operand(esp, 1 * kPointerSize), edi); | 827 __ mov(Operand(esp, 1 * kPointerSize), edi); |
835 | 828 |
836 // Step 4 move return address to the correct location | 829 // Step 4 move return address to the correct location |
837 __ mov(edi, Operand(esp, eax, times_pointer_size, 3 * kPointerSize)); | 830 __ mov(edi, Operand(esp, eax, times_pointer_size, 3 * kPointerSize)); |
838 __ mov(Operand(esp, 2 * kPointerSize), edi); | 831 __ mov(Operand(esp, 2 * kPointerSize), edi); |
839 | 832 |
840 // Slot meant for receiver contains return address. Reset it so that | |
841 // we will not incorrectly interpret return address as an object. | |
842 __ mov(Operand(esp, eax, times_pointer_size, 3 * kPointerSize), Immediate(0)); | |
843 | |
844 // Step 5 copy arguments to correct locations. | 833 // Step 5 copy arguments to correct locations. |
845 __ mov(edx, eax); | 834 if (is_receiver_available) { |
rmcilroy
2016/09/06 10:59:35
ditto (if possible)
mythria
2016/09/07 08:59:45
This is difficult. We do not have any free registe
| |
835 __ mov(edx, eax); | |
836 __ add(edx, Immediate(1)); | |
837 } else { | |
838 // Slot meant for receiver contains return address. Reset it so that | |
839 // we will not incorrectly interpret return address as an object. | |
840 __ mov(Operand(esp, eax, times_pointer_size, 3 * kPointerSize), | |
841 Immediate(0)); | |
842 __ mov(edx, eax); | |
843 } | |
846 | 844 |
847 Label loop_header, loop_check; | 845 Label loop_header, loop_check; |
848 __ jmp(&loop_check); | 846 __ jmp(&loop_check); |
849 __ bind(&loop_header); | 847 __ bind(&loop_header); |
850 __ mov(edi, Operand(ecx, 0)); | 848 __ mov(edi, Operand(ecx, 0)); |
851 __ mov(Operand(esp, edx, times_pointer_size, 2 * kPointerSize), edi); | 849 __ mov(Operand(esp, edx, times_pointer_size, 2 * kPointerSize), edi); |
852 __ sub(ecx, Immediate(kPointerSize)); | 850 __ sub(ecx, Immediate(kPointerSize)); |
853 __ sub(edx, Immediate(1)); | 851 __ sub(edx, Immediate(1)); |
854 __ bind(&loop_check); | 852 __ bind(&loop_check); |
855 __ cmp(edx, Immediate(0)); | 853 __ cmp(edx, Immediate(0)); |
856 __ j(greater, &loop_header, Label::kNear); | 854 __ j(greater, &loop_header, Label::kNear); |
857 | 855 |
858 // Restore edi and edx. | 856 // Restore edi and edx. |
859 __ Pop(edx); | 857 __ Pop(edx); |
860 __ Pop(edi); | 858 __ Pop(edi); |
859 } | |
860 | |
861 } // end anonymous namespace | |
862 | |
863 // static | |
864 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( | |
865 MacroAssembler* masm, CallableType construct_type) { | |
866 // ----------- S t a t e ------------- | |
867 // -- eax : the number of arguments (not including the receiver) | |
868 // -- edx : the new target | |
869 // -- edi : the constructor | |
870 // -- ebx : allocation site feedback (if available or undefined) | |
871 // -- ecx : the address of the first argument to be pushed. Subsequent | |
872 // arguments should be consecutive above this, in the same order as | |
873 // they are to be pushed onto the stack. | |
874 // ----------------------------------- | |
875 | |
876 // Push arguments and move return address to the top of stack. | |
877 Generate_InterpreterPushArgsAndReturnAddress(masm, false); | |
861 | 878 |
862 __ AssertUndefinedOrAllocationSite(ebx); | 879 __ AssertUndefinedOrAllocationSite(ebx); |
863 if (construct_type == CallableType::kJSFunction) { | 880 if (construct_type == CallableType::kJSFunction) { |
864 // Tail call to the function-specific construct stub (still in the caller | 881 // Tail call to the function-specific construct stub (still in the caller |
865 // context at this point). | 882 // context at this point). |
866 __ AssertFunction(edi); | 883 __ AssertFunction(edi); |
867 | 884 |
868 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 885 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
869 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); | 886 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); |
870 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 887 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
871 __ jmp(ecx); | 888 __ jmp(ecx); |
872 } else { | 889 } else { |
873 DCHECK_EQ(construct_type, CallableType::kAny); | 890 DCHECK_EQ(construct_type, CallableType::kAny); |
874 | 891 |
875 // Call the constructor with unmodified eax, edi, edx values. | 892 // Call the constructor with unmodified eax, edi, edx values. |
876 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 893 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
877 } | 894 } |
878 } | 895 } |
879 | 896 |
897 // static | |
898 void Builtins::Generate_InterpreterPushArgsAndConstructArray( | |
899 MacroAssembler* masm) { | |
900 // ----------- S t a t e ------------- | |
901 // -- eax : the number of arguments (not including the receiver) | |
902 // -- edx : the target to call checked to be Array function. | |
903 // -- ebx : the allocation site feedback | |
904 // -- ecx : the address of the first argument to be pushed. Subsequent | |
905 // arguments should be consecutive above this, in the same order as | |
906 // they are to be pushed onto the stack. | |
907 // ----------------------------------- | |
908 | |
909 // Push arguments and move return address to the top of stack. | |
910 Generate_InterpreterPushArgsAndReturnAddress(masm, true); | |
911 | |
912 // Array constructor expects constructor in edi. It is same as edx here. | |
913 __ Move(edi, edx); | |
914 | |
915 ArrayConstructorStub stub(masm->isolate()); | |
916 __ TailCallStub(&stub); | |
917 } | |
918 | |
880 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { | 919 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { |
881 // Set the return address to the correct point in the interpreter entry | 920 // Set the return address to the correct point in the interpreter entry |
882 // trampoline. | 921 // trampoline. |
883 Smi* interpreter_entry_return_pc_offset( | 922 Smi* interpreter_entry_return_pc_offset( |
884 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); | 923 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); |
885 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); | 924 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); |
886 __ LoadHeapObject(ebx, | 925 __ LoadHeapObject(ebx, |
887 masm->isolate()->builtins()->InterpreterEntryTrampoline()); | 926 masm->isolate()->builtins()->InterpreterEntryTrampoline()); |
888 __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() + | 927 __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() + |
889 Code::kHeaderSize - kHeapObjectTag)); | 928 Code::kHeaderSize - kHeapObjectTag)); |
(...skipping 2231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3121 | 3160 |
3122 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { | 3161 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
3123 Generate_OnStackReplacementHelper(masm, true); | 3162 Generate_OnStackReplacementHelper(masm, true); |
3124 } | 3163 } |
3125 | 3164 |
3126 #undef __ | 3165 #undef __ |
3127 } // namespace internal | 3166 } // namespace internal |
3128 } // namespace v8 | 3167 } // namespace v8 |
3129 | 3168 |
3130 #endif // V8_TARGET_ARCH_IA32 | 3169 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |