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

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

Issue 2307903002: [Interpreter] Collect allocation site feedback in call bytecode handler. (Closed)
Patch Set: ia32, arm and arm64 ports. 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
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 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698