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

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

Issue 2293253007: X87: [Interpreter] Collect type feedback for 'new' in the 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 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 __ push(edi); 698 __ push(edi);
699 __ CallRuntime(Runtime::kCompileBaseline); 699 __ CallRuntime(Runtime::kCompileBaseline);
700 700
701 // Restore return value. 701 // Restore return value.
702 __ pop(eax); 702 __ pop(eax);
703 } 703 }
704 __ ret(0); 704 __ ret(0);
705 } 705 }
706 706
707 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 707 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
708 Register array_limit) { 708 Register array_limit,
709 Register start_address) {
709 // ----------- S t a t e ------------- 710 // ----------- S t a t e -------------
710 // -- ebx : Pointer to the last argument in the args array. 711 // -- start_address : Pointer to the last argument in the args array.
711 // -- array_limit : Pointer to one before the first argument in the 712 // -- array_limit : Pointer to one before the first argument in the
712 // args array. 713 // args array.
713 // ----------------------------------- 714 // -----------------------------------
714 Label loop_header, loop_check; 715 Label loop_header, loop_check;
715 __ jmp(&loop_check); 716 __ jmp(&loop_check);
716 __ bind(&loop_header); 717 __ bind(&loop_header);
717 __ Push(Operand(ebx, 0)); 718 __ Push(Operand(start_address, 0));
718 __ sub(ebx, Immediate(kPointerSize)); 719 __ sub(start_address, Immediate(kPointerSize));
719 __ bind(&loop_check); 720 __ bind(&loop_check);
720 __ cmp(ebx, array_limit); 721 __ cmp(start_address, array_limit);
721 __ j(greater, &loop_header, Label::kNear); 722 __ j(greater, &loop_header, Label::kNear);
722 } 723 }
723 724
724 // static 725 // static
725 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 726 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
726 MacroAssembler* masm, TailCallMode tail_call_mode, 727 MacroAssembler* masm, TailCallMode tail_call_mode,
727 CallableType function_type) { 728 CallableType function_type) {
728 // ----------- S t a t e ------------- 729 // ----------- S t a t e -------------
729 // -- eax : the number of arguments (not including the receiver) 730 // -- eax : the number of arguments (not including the receiver)
730 // -- ebx : the address of the first argument to be pushed. Subsequent 731 // -- ebx : the address of the first argument to be pushed. Subsequent
731 // arguments should be consecutive above this, in the same order as 732 // arguments should be consecutive above this, in the same order as
732 // they are to be pushed onto the stack. 733 // they are to be pushed onto the stack.
733 // -- edi : the target to call (can be any Object). 734 // -- edi : the target to call (can be any Object).
734 // ----------------------------------- 735 // -----------------------------------
735 736
736 // Pop return address to allow tail-call after pushing arguments. 737 // Pop return address to allow tail-call after pushing arguments.
737 __ Pop(edx); 738 __ Pop(edx);
738 739
739 // Find the address of the last argument. 740 // Find the address of the last argument.
740 __ mov(ecx, eax); 741 __ mov(ecx, eax);
741 __ add(ecx, Immediate(1)); // Add one for receiver. 742 __ add(ecx, Immediate(1)); // Add one for receiver.
742 __ shl(ecx, kPointerSizeLog2); 743 __ shl(ecx, kPointerSizeLog2);
743 __ neg(ecx); 744 __ neg(ecx);
744 __ add(ecx, ebx); 745 __ add(ecx, ebx);
745 746
746 Generate_InterpreterPushArgs(masm, ecx); 747 // TODO(mythria): Add a stack check before pushing the arguments.
748 Generate_InterpreterPushArgs(masm, ecx, ebx);
747 749
748 // Call the target. 750 // Call the target.
749 __ Push(edx); // Re-push return address. 751 __ Push(edx); // Re-push return address.
750 752
751 if (function_type == CallableType::kJSFunction) { 753 if (function_type == CallableType::kJSFunction) {
752 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, 754 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
753 tail_call_mode), 755 tail_call_mode),
754 RelocInfo::CODE_TARGET); 756 RelocInfo::CODE_TARGET);
755 } else { 757 } else {
756 DCHECK_EQ(function_type, CallableType::kAny); 758 DCHECK_EQ(function_type, CallableType::kAny);
757 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 759 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
758 tail_call_mode), 760 tail_call_mode),
759 RelocInfo::CODE_TARGET); 761 RelocInfo::CODE_TARGET);
760 } 762 }
761 } 763 }
762 764
763 // static 765 // static
764 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { 766 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
767 MacroAssembler* masm, CallableType construct_type) {
765 // ----------- S t a t e ------------- 768 // ----------- S t a t e -------------
766 // -- eax : the number of arguments (not including the receiver) 769 // -- eax : the number of arguments (not including the receiver)
767 // -- edx : the new target 770 // -- edx : the new target
768 // -- edi : the constructor 771 // -- edi : the constructor
769 // -- ebx : the address of the first argument to be pushed. Subsequent 772 // -- ebx : allocation site feedback (if available or undefined)
773 // -- ecx : the address of the first argument to be pushed. Subsequent
770 // arguments should be consecutive above this, in the same order as 774 // arguments should be consecutive above this, in the same order as
771 // they are to be pushed onto the stack. 775 // they are to be pushed onto the stack.
772 // ----------------------------------- 776 // -----------------------------------
773 777
774 // Pop return address to allow tail-call after pushing arguments. 778 // Store edi, edx onto the stack. We need two extra registers
775 __ Pop(ecx); 779 // so store edi, edx temporarily on stack.
780 __ Push(edi);
781 __ Push(edx);
776 782
777 // Push edi in the slot meant for receiver. We need an extra register 783 // We have to pop return address and the two temporary registers before we
778 // so store edi temporarily on stack. 784 // can push arguments onto the stack. we do not have any free registers so
779 __ Push(edi); 785 // update the stack and copy them into the correct places on the stack.
786 // current stack =====> required stack layout
787 // | | | edx | (2) <-- esp(1)
788 // | | | edi | (3)
789 // | | | return addr | (4)
790 // | | | arg N | (5)
791 // | edx | <-- esp | .... |
792 // | edi | | arg 0 |
793 // | return addr | | receiver slot |
780 794
781 // Find the address of the last argument. 795 // First increment the stack pointer to the correct location.
782 __ mov(edi, eax); 796 // we need additional slots for arguments and the receiver.
783 __ neg(edi); 797 // Step 1 - compute the required increment to the stack.
784 __ shl(edi, kPointerSizeLog2); 798 __ mov(edx, eax);
785 __ add(edi, ebx); 799 __ shl(edx, kPointerSizeLog2);
800 __ add(edx, Immediate(kPointerSize));
786 801
787 Generate_InterpreterPushArgs(masm, edi); 802 #ifdef _MSC_VER
803 // TODO(mythria): Move it to macro assembler.
804 // 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
806 // page. Check this:
807 // https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
808 const int page_size = 4 * 1024;
809 Label check_offset, update_stack_pointer;
810 __ bind(&check_offset);
811 __ cmp(edx, page_size);
812 __ j(less, &update_stack_pointer);
813 __ sub(esp, Immediate(page_size));
814 // Just to touch the page, before we increment further.
815 __ mov(Operand(esp, 0), Immediate(0));
816 __ sub(edx, Immediate(page_size));
817 __ jmp(&check_offset);
818 __ bind(&update_stack_pointer);
819 #endif
788 820
789 // Restore the constructor from slot on stack. It was pushed at the slot 821 // TODO(mythria): Add a stack check before updating the stack pointer.
790 // meant for receiver.
791 __ mov(edi, Operand(esp, eax, times_pointer_size, 0));
792 822
793 // Re-push return address. 823 // Step 1 - Update the stack pointer.
794 __ Push(ecx); 824 __ sub(esp, edx);
795 825
796 // Call the constructor with unmodified eax, edi, ebi values. 826 // Step 2 move edx to the correct location. Move edx first otherwise
797 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 827 // we may overwrite when eax = 0 or 1, basically when the source and
828 // destination overlap. We at least need one extra slot for receiver,
829 // so no extra checks are required to avoid copy.
830 __ mov(edi, Operand(esp, eax, times_pointer_size, 1 * kPointerSize));
831 __ mov(Operand(esp, 0), edi);
832
833 // Step 3 move edi to the correct location
834 __ mov(edi, Operand(esp, eax, times_pointer_size, 2 * kPointerSize));
835 __ mov(Operand(esp, 1 * kPointerSize), edi);
836
837 // Step 4 move return address to the correct location
838 __ mov(edi, Operand(esp, eax, times_pointer_size, 3 * kPointerSize));
839 __ mov(Operand(esp, 2 * kPointerSize), edi);
840
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
845 // Step 5 copy arguments to correct locations.
846 __ mov(edx, eax);
847
848 Label loop_header, loop_check;
849 __ jmp(&loop_check);
850 __ bind(&loop_header);
851 __ mov(edi, Operand(ecx, 0));
852 __ mov(Operand(esp, edx, times_pointer_size, 2 * kPointerSize), edi);
853 __ sub(ecx, Immediate(kPointerSize));
854 __ sub(edx, Immediate(1));
855 __ bind(&loop_check);
856 __ cmp(edx, Immediate(0));
857 __ j(greater, &loop_header, Label::kNear);
858
859 // Restore edi and edx.
860 __ Pop(edx);
861 __ Pop(edi);
862
863 __ AssertUndefinedOrAllocationSite(ebx);
864 if (construct_type == CallableType::kJSFunction) {
865 // Tail call to the function-specific construct stub (still in the caller
866 // context at this point).
867 __ AssertFunction(edi);
868
869 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
870 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
871 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
872 __ jmp(ecx);
873 } else {
874 DCHECK_EQ(construct_type, CallableType::kAny);
875
876 // Call the constructor with unmodified eax, edi, edx values.
877 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
878 }
798 } 879 }
799 880
800 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { 881 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
801 // Set the return address to the correct point in the interpreter entry 882 // Set the return address to the correct point in the interpreter entry
802 // trampoline. 883 // trampoline.
803 Smi* interpreter_entry_return_pc_offset( 884 Smi* interpreter_entry_return_pc_offset(
804 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); 885 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
805 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); 886 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
806 __ LoadHeapObject(ebx, 887 __ LoadHeapObject(ebx,
807 masm->isolate()->builtins()->InterpreterEntryTrampoline()); 888 masm->isolate()->builtins()->InterpreterEntryTrampoline());
(...skipping 2257 matching lines...) Expand 10 before | Expand all | Expand 10 after
3065 3146
3066 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3147 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3067 Generate_OnStackReplacementHelper(masm, true); 3148 Generate_OnStackReplacementHelper(masm, true);
3068 } 3149 }
3069 3150
3070 #undef __ 3151 #undef __
3071 } // namespace internal 3152 } // namespace internal
3072 } // namespace v8 3153 } // namespace v8
3073 3154
3074 #endif // V8_TARGET_ARCH_X87 3155 #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