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

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

Issue 2319123004: X87: [Interpreter] Collect allocation site feedback in call bytecode handler. (Closed)
Patch Set: Created 4 years, 3 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 | « no previous file | src/x87/interface-descriptors-x87.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_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 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 tail_call_mode), 755 tail_call_mode),
756 RelocInfo::CODE_TARGET); 756 RelocInfo::CODE_TARGET);
757 } else { 757 } else {
758 DCHECK_EQ(function_type, CallableType::kAny); 758 DCHECK_EQ(function_type, CallableType::kAny);
759 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 759 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
760 tail_call_mode), 760 tail_call_mode),
761 RelocInfo::CODE_TARGET); 761 RelocInfo::CODE_TARGET);
762 } 762 }
763 } 763 }
764 764
765 // static 765 namespace {
766 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
767 MacroAssembler* masm, CallableType construct_type) {
768 // ----------- S t a t e -------------
769 // -- eax : the number of arguments (not including the receiver)
770 // -- edx : the new target
771 // -- edi : the constructor
772 // -- ebx : allocation site feedback (if available or undefined)
773 // -- ecx : the address of the first argument to be pushed. Subsequent
774 // arguments should be consecutive above this, in the same order as
775 // they are to be pushed onto the stack.
776 // -----------------------------------
777 766
778 // Store edi, edx onto the stack. We need two extra registers 767 // This function modified start_addr, and only reads the contents of num_args
779 // so store edi, edx temporarily on stack. 768 // register. scratch1 and scratch2 are used as temporary registers. Their
780 __ Push(edi); 769 // original values are restored after the use.
781 __ Push(edx); 770 void Generate_InterpreterPushArgsAndReturnAddress(
771 MacroAssembler* masm, Register num_args, Register start_addr,
772 Register scratch1, Register scratch2, bool receiver_in_args) {
773 // Store scratch2, scratch1 onto the stack. We need to restore the original
774 // values
775 // so store scratch2, scratch1 temporarily on stack.
776 __ Push(scratch2);
777 __ Push(scratch1);
782 778
783 // We have to pop return address and the two temporary registers before we 779 // We have to pop return address and the two temporary registers before we
784 // can push arguments onto the stack. we do not have any free registers so 780 // can push arguments onto the stack. we do not have any free registers so
785 // update the stack and copy them into the correct places on the stack. 781 // update the stack and copy them into the correct places on the stack.
786 // current stack =====> required stack layout 782 // current stack =====> required stack layout
787 // | | | edx | (2) <-- esp(1) 783 // | | | scratch1 | (2) <-- esp(1)
788 // | | | edi | (3) 784 // | | | scratch2 | (3)
789 // | | | return addr | (4) 785 // | | | return addr | (4)
790 // | | | arg N | (5) 786 // | | | arg N | (5)
791 // | edx | <-- esp | .... | 787 // | scratch1 | <-- esp | .... |
792 // | edi | | arg 0 | 788 // | scratch2 | | arg 0 |
793 // | return addr | | receiver slot | 789 // | return addr | | receiver slot |
794 790
795 // First increment the stack pointer to the correct location. 791 // First increment the stack pointer to the correct location.
796 // we need additional slots for arguments and the receiver. 792 // we need additional slots for arguments and the receiver.
797 // Step 1 - compute the required increment to the stack. 793 // Step 1 - compute the required increment to the stack.
798 __ mov(edx, eax); 794 __ mov(scratch1, num_args);
799 __ shl(edx, kPointerSizeLog2); 795 __ shl(scratch1, kPointerSizeLog2);
800 __ add(edx, Immediate(kPointerSize)); 796 __ add(scratch1, Immediate(kPointerSize));
801 797
802 #ifdef _MSC_VER 798 #ifdef _MSC_VER
803 // TODO(mythria): Move it to macro assembler. 799 // TODO(mythria): Move it to macro assembler.
804 // In windows, we cannot increment the stack size by more than one page 800 // In windows, we cannot increment the stack size by more than one page
805 // (mimimum page size is 4KB) without accessing at least one byte on the 801 // (mimimum page size is 4KB) without accessing at least one byte on the
806 // page. Check this: 802 // page. Check this:
807 // https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx. 803 // https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
808 const int page_size = 4 * 1024; 804 const int page_size = 4 * 1024;
809 Label check_offset, update_stack_pointer; 805 Label check_offset, update_stack_pointer;
810 __ bind(&check_offset); 806 __ bind(&check_offset);
811 __ cmp(edx, page_size); 807 __ cmp(scratch1, page_size);
812 __ j(less, &update_stack_pointer); 808 __ j(less, &update_stack_pointer);
813 __ sub(esp, Immediate(page_size)); 809 __ sub(esp, Immediate(page_size));
814 // Just to touch the page, before we increment further. 810 // Just to touch the page, before we increment further.
815 __ mov(Operand(esp, 0), Immediate(0)); 811 __ mov(Operand(esp, 0), Immediate(0));
816 __ sub(edx, Immediate(page_size)); 812 __ sub(scratch1, Immediate(page_size));
817 __ jmp(&check_offset); 813 __ jmp(&check_offset);
818 __ bind(&update_stack_pointer); 814 __ bind(&update_stack_pointer);
819 #endif 815 #endif
820 816
821 // TODO(mythria): Add a stack check before updating the stack pointer. 817 // TODO(mythria): Add a stack check before updating the stack pointer.
822 818
823 // Step 1 - Update the stack pointer. 819 // Step 1 - Update the stack pointer.
824 __ sub(esp, edx); 820 __ sub(esp, scratch1);
825 821
826 // Step 2 move edx to the correct location. Move edx first otherwise 822 // Step 2 move scratch1 to the correct location. Move scratch1 first otherwise
827 // we may overwrite when eax = 0 or 1, basically when the source and 823 // we may overwrite when num_args = 0 or 1, basically when the source and
828 // destination overlap. We at least need one extra slot for receiver, 824 // destination overlap. We at least need one extra slot for receiver,
829 // so no extra checks are required to avoid copy. 825 // so no extra checks are required to avoid copy.
830 __ mov(edi, Operand(esp, eax, times_pointer_size, 1 * kPointerSize)); 826 __ mov(scratch1,
831 __ mov(Operand(esp, 0), edi); 827 Operand(esp, num_args, times_pointer_size, 1 * kPointerSize));
828 __ mov(Operand(esp, 0), scratch1);
832 829
833 // Step 3 move edi to the correct location 830 // Step 3 move scratch2 to the correct location
834 __ mov(edi, Operand(esp, eax, times_pointer_size, 2 * kPointerSize)); 831 __ mov(scratch1,
835 __ mov(Operand(esp, 1 * kPointerSize), edi); 832 Operand(esp, num_args, times_pointer_size, 2 * kPointerSize));
833 __ mov(Operand(esp, 1 * kPointerSize), scratch1);
836 834
837 // Step 4 move return address to the correct location 835 // Step 4 move return address to the correct location
838 __ mov(edi, Operand(esp, eax, times_pointer_size, 3 * kPointerSize)); 836 __ mov(scratch1,
839 __ mov(Operand(esp, 2 * kPointerSize), edi); 837 Operand(esp, num_args, times_pointer_size, 3 * kPointerSize));
840 838 __ mov(Operand(esp, 2 * kPointerSize), scratch1);
841 // Slot meant for receiver contains return address. Reset it so that
842 // we will not incorrectly interpret return address as an object.
843 __ mov(Operand(esp, eax, times_pointer_size, 3 * kPointerSize), Immediate(0));
844 839
845 // Step 5 copy arguments to correct locations. 840 // Step 5 copy arguments to correct locations.
846 __ mov(edx, eax); 841 if (receiver_in_args) {
842 __ mov(scratch1, num_args);
843 __ add(scratch1, Immediate(1));
844 } else {
845 // Slot meant for receiver contains return address. Reset it so that
846 // we will not incorrectly interpret return address as an object.
847 __ mov(Operand(esp, num_args, times_pointer_size, 3 * kPointerSize),
848 Immediate(0));
849 __ mov(scratch1, num_args);
850 }
847 851
848 Label loop_header, loop_check; 852 Label loop_header, loop_check;
849 __ jmp(&loop_check); 853 __ jmp(&loop_check);
850 __ bind(&loop_header); 854 __ bind(&loop_header);
851 __ mov(edi, Operand(ecx, 0)); 855 __ mov(scratch2, Operand(start_addr, 0));
852 __ mov(Operand(esp, edx, times_pointer_size, 2 * kPointerSize), edi); 856 __ mov(Operand(esp, scratch1, times_pointer_size, 2 * kPointerSize),
853 __ sub(ecx, Immediate(kPointerSize)); 857 scratch2);
854 __ sub(edx, Immediate(1)); 858 __ sub(start_addr, Immediate(kPointerSize));
859 __ sub(scratch1, Immediate(1));
855 __ bind(&loop_check); 860 __ bind(&loop_check);
856 __ cmp(edx, Immediate(0)); 861 __ cmp(scratch1, Immediate(0));
857 __ j(greater, &loop_header, Label::kNear); 862 __ j(greater, &loop_header, Label::kNear);
858 863
859 // Restore edi and edx. 864 // Restore scratch1 and scratch2.
860 __ Pop(edx); 865 __ Pop(scratch1);
861 __ Pop(edi); 866 __ Pop(scratch2);
867 }
868
869 } // end anonymous namespace
870
871 // static
872 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
873 MacroAssembler* masm, CallableType construct_type) {
874 // ----------- S t a t e -------------
875 // -- eax : the number of arguments (not including the receiver)
876 // -- edx : the new target
877 // -- edi : the constructor
878 // -- ebx : allocation site feedback (if available or undefined)
879 // -- ecx : the address of the first argument to be pushed. Subsequent
880 // arguments should be consecutive above this, in the same order as
881 // they are to be pushed onto the stack.
882 // -----------------------------------
883
884 // Push arguments and move return address to the top of stack.
885 // The eax register is readonly. The ecx register will be modified. The edx
886 // and edi registers will be modified but restored to their original values.
887 Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false);
862 888
863 __ AssertUndefinedOrAllocationSite(ebx); 889 __ AssertUndefinedOrAllocationSite(ebx);
864 if (construct_type == CallableType::kJSFunction) { 890 if (construct_type == CallableType::kJSFunction) {
865 // Tail call to the function-specific construct stub (still in the caller 891 // Tail call to the function-specific construct stub (still in the caller
866 // context at this point). 892 // context at this point).
867 __ AssertFunction(edi); 893 __ AssertFunction(edi);
868 894
869 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 895 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
870 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); 896 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
871 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); 897 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
872 __ jmp(ecx); 898 __ jmp(ecx);
873 } else { 899 } else {
874 DCHECK_EQ(construct_type, CallableType::kAny); 900 DCHECK_EQ(construct_type, CallableType::kAny);
875 901
876 // Call the constructor with unmodified eax, edi, edx values. 902 // Call the constructor with unmodified eax, edi, edx values.
877 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 903 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
878 } 904 }
879 } 905 }
880 906
907 // static
908 void Builtins::Generate_InterpreterPushArgsAndConstructArray(
909 MacroAssembler* masm) {
910 // ----------- S t a t e -------------
911 // -- eax : the number of arguments (not including the receiver)
912 // -- edx : the target to call checked to be Array function.
913 // -- ebx : the allocation site feedback
914 // -- ecx : the address of the first argument to be pushed. Subsequent
915 // arguments should be consecutive above this, in the same order as
916 // they are to be pushed onto the stack.
917 // -----------------------------------
918
919 // Push arguments and move return address to the top of stack.
920 // The eax register is readonly. The ecx register will be modified. The edx
921 // and edi registers will be modified but restored to their original values.
922 Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, ebx, true);
923
924 // Array constructor expects constructor in edi. It is same as edx here.
925 __ Move(edi, edx);
926
927 ArrayConstructorStub stub(masm->isolate());
928 __ TailCallStub(&stub);
929 }
930
881 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { 931 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
882 // Set the return address to the correct point in the interpreter entry 932 // Set the return address to the correct point in the interpreter entry
883 // trampoline. 933 // trampoline.
884 Smi* interpreter_entry_return_pc_offset( 934 Smi* interpreter_entry_return_pc_offset(
885 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); 935 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
886 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); 936 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
887 __ LoadHeapObject(ebx, 937 __ LoadHeapObject(ebx,
888 masm->isolate()->builtins()->InterpreterEntryTrampoline()); 938 masm->isolate()->builtins()->InterpreterEntryTrampoline());
889 __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() + 939 __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() +
890 Code::kHeaderSize - kHeapObjectTag)); 940 Code::kHeaderSize - kHeapObjectTag));
(...skipping 2255 matching lines...) Expand 10 before | Expand all | Expand 10 after
3146 3196
3147 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3197 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3148 Generate_OnStackReplacementHelper(masm, true); 3198 Generate_OnStackReplacementHelper(masm, true);
3149 } 3199 }
3150 3200
3151 #undef __ 3201 #undef __
3152 } // namespace internal 3202 } // namespace internal
3153 } // namespace v8 3203 } // namespace v8
3154 3204
3155 #endif // V8_TARGET_ARCH_X87 3205 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698