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

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

Issue 2649143002: [Turbofan] Implement call with spread bytecode in assembly code. (Closed)
Patch Set: Rename PushArgsMode to InterpreterPushArgsMode Created 3 years, 11 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/builtins/s390/builtins-s390.cc ('k') | src/builtins/x87/builtins-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_X64 5 #if V8_TARGET_ARCH_X64
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 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 __ Push(Operand(start_address, 0)); 758 __ Push(Operand(start_address, 0));
759 __ subp(start_address, Immediate(kPointerSize)); 759 __ subp(start_address, Immediate(kPointerSize));
760 __ bind(&loop_check); 760 __ bind(&loop_check);
761 __ cmpp(start_address, scratch); 761 __ cmpp(start_address, scratch);
762 __ j(greater, &loop_header, Label::kNear); 762 __ j(greater, &loop_header, Label::kNear);
763 } 763 }
764 764
765 // static 765 // static
766 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 766 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
767 MacroAssembler* masm, TailCallMode tail_call_mode, 767 MacroAssembler* masm, TailCallMode tail_call_mode,
768 CallableType function_type) { 768 InterpreterPushArgsMode mode) {
769 // ----------- S t a t e ------------- 769 // ----------- S t a t e -------------
770 // -- rax : the number of arguments (not including the receiver) 770 // -- rax : the number of arguments (not including the receiver)
771 // -- rbx : the address of the first argument to be pushed. Subsequent 771 // -- rbx : the address of the first argument to be pushed. Subsequent
772 // arguments should be consecutive above this, in the same order as 772 // arguments should be consecutive above this, in the same order as
773 // they are to be pushed onto the stack. 773 // they are to be pushed onto the stack.
774 // -- rdi : the target to call (can be any Object). 774 // -- rdi : the target to call (can be any Object).
775 // ----------------------------------- 775 // -----------------------------------
776 Label stack_overflow; 776 Label stack_overflow;
777 777
778 // Number of values to be pushed. 778 // Number of values to be pushed.
779 __ Move(rcx, rax); 779 __ Move(rcx, rax);
780 __ addp(rcx, Immediate(1)); // Add one for receiver. 780 __ addp(rcx, Immediate(1)); // Add one for receiver.
781 781
782 // Add a stack check before pushing arguments. 782 // Add a stack check before pushing arguments.
783 Generate_StackOverflowCheck(masm, rcx, rdx, r8, &stack_overflow); 783 Generate_StackOverflowCheck(masm, rcx, rdx, r8, &stack_overflow);
784 784
785 // Pop return address to allow tail-call after pushing arguments. 785 // Pop return address to allow tail-call after pushing arguments.
786 __ PopReturnAddressTo(kScratchRegister); 786 __ PopReturnAddressTo(kScratchRegister);
787 787
788 // rbx and rdx will be modified. 788 // rbx and rdx will be modified.
789 Generate_InterpreterPushArgs(masm, rcx, rbx, rdx); 789 Generate_InterpreterPushArgs(masm, rcx, rbx, rdx);
790 790
791 // Call the target. 791 // Call the target.
792 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. 792 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
793 793
794 if (function_type == CallableType::kJSFunction) { 794 if (mode == InterpreterPushArgsMode::kJSFunction) {
795 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, 795 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
796 tail_call_mode), 796 tail_call_mode),
797 RelocInfo::CODE_TARGET); 797 RelocInfo::CODE_TARGET);
798 } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
799 __ Jump(masm->isolate()->builtins()->CallWithSpread(),
800 RelocInfo::CODE_TARGET);
798 } else { 801 } else {
799 DCHECK_EQ(function_type, CallableType::kAny);
800 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 802 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
801 tail_call_mode), 803 tail_call_mode),
802 RelocInfo::CODE_TARGET); 804 RelocInfo::CODE_TARGET);
803 } 805 }
804 806
805 // Throw stack overflow exception. 807 // Throw stack overflow exception.
806 __ bind(&stack_overflow); 808 __ bind(&stack_overflow);
807 { 809 {
808 __ TailCallRuntime(Runtime::kThrowStackOverflow); 810 __ TailCallRuntime(Runtime::kThrowStackOverflow);
809 // This should be unreachable. 811 // This should be unreachable.
810 __ int3(); 812 __ int3();
811 } 813 }
812 } 814 }
813 815
814 // static 816 // static
815 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 817 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
816 MacroAssembler* masm, PushArgsConstructMode mode) { 818 MacroAssembler* masm, InterpreterPushArgsMode mode) {
817 // ----------- S t a t e ------------- 819 // ----------- S t a t e -------------
818 // -- rax : the number of arguments (not including the receiver) 820 // -- rax : the number of arguments (not including the receiver)
819 // -- rdx : the new target (either the same as the constructor or 821 // -- rdx : the new target (either the same as the constructor or
820 // the JSFunction on which new was invoked initially) 822 // the JSFunction on which new was invoked initially)
821 // -- rdi : the constructor to call (can be any Object) 823 // -- rdi : the constructor to call (can be any Object)
822 // -- rbx : the allocation site feedback if available, undefined otherwise 824 // -- rbx : the allocation site feedback if available, undefined otherwise
823 // -- rcx : the address of the first argument to be pushed. Subsequent 825 // -- rcx : the address of the first argument to be pushed. Subsequent
824 // arguments should be consecutive above this, in the same order as 826 // arguments should be consecutive above this, in the same order as
825 // they are to be pushed onto the stack. 827 // they are to be pushed onto the stack.
826 // ----------------------------------- 828 // -----------------------------------
827 Label stack_overflow; 829 Label stack_overflow;
828 830
829 // Add a stack check before pushing arguments. 831 // Add a stack check before pushing arguments.
830 Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow); 832 Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow);
831 833
832 // Pop return address to allow tail-call after pushing arguments. 834 // Pop return address to allow tail-call after pushing arguments.
833 __ PopReturnAddressTo(kScratchRegister); 835 __ PopReturnAddressTo(kScratchRegister);
834 836
835 // Push slot for the receiver to be constructed. 837 // Push slot for the receiver to be constructed.
836 __ Push(Immediate(0)); 838 __ Push(Immediate(0));
837 839
838 // rcx and r8 will be modified. 840 // rcx and r8 will be modified.
839 Generate_InterpreterPushArgs(masm, rax, rcx, r8); 841 Generate_InterpreterPushArgs(masm, rax, rcx, r8);
840 842
841 // Push return address in preparation for the tail-call. 843 // Push return address in preparation for the tail-call.
842 __ PushReturnAddressFrom(kScratchRegister); 844 __ PushReturnAddressFrom(kScratchRegister);
843 845
844 __ AssertUndefinedOrAllocationSite(rbx); 846 __ AssertUndefinedOrAllocationSite(rbx);
845 if (mode == PushArgsConstructMode::kJSFunction) { 847 if (mode == InterpreterPushArgsMode::kJSFunction) {
846 // Tail call to the function-specific construct stub (still in the caller 848 // Tail call to the function-specific construct stub (still in the caller
847 // context at this point). 849 // context at this point).
848 __ AssertFunction(rdi); 850 __ AssertFunction(rdi);
849 851
850 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 852 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
851 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); 853 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
852 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 854 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
853 // Jump to the constructor function (rax, rbx, rdx passed on). 855 // Jump to the constructor function (rax, rbx, rdx passed on).
854 __ jmp(rcx); 856 __ jmp(rcx);
855 } else if (mode == PushArgsConstructMode::kWithFinalSpread) { 857 } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
856 // Call the constructor (rax, rdx, rdi passed on). 858 // Call the constructor (rax, rdx, rdi passed on).
857 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(), 859 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(),
858 RelocInfo::CODE_TARGET); 860 RelocInfo::CODE_TARGET);
859 } else { 861 } else {
860 DCHECK_EQ(PushArgsConstructMode::kOther, mode); 862 DCHECK_EQ(InterpreterPushArgsMode::kOther, mode);
861 // Call the constructor (rax, rdx, rdi passed on). 863 // Call the constructor (rax, rdx, rdi passed on).
862 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 864 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
863 } 865 }
864 866
865 // Throw stack overflow exception. 867 // Throw stack overflow exception.
866 __ bind(&stack_overflow); 868 __ bind(&stack_overflow);
867 { 869 {
868 __ TailCallRuntime(Runtime::kThrowStackOverflow); 870 __ TailCallRuntime(Runtime::kThrowStackOverflow);
869 // This should be unreachable. 871 // This should be unreachable.
870 __ int3(); 872 __ int3();
(...skipping 1883 matching lines...) Expand 10 before | Expand all | Expand 10 after
2754 2756
2755 // 3. Call to something that is not callable. 2757 // 3. Call to something that is not callable.
2756 __ bind(&non_callable); 2758 __ bind(&non_callable);
2757 { 2759 {
2758 FrameScope scope(masm, StackFrame::INTERNAL); 2760 FrameScope scope(masm, StackFrame::INTERNAL);
2759 __ Push(rdi); 2761 __ Push(rdi);
2760 __ CallRuntime(Runtime::kThrowCalledNonCallable); 2762 __ CallRuntime(Runtime::kThrowCalledNonCallable);
2761 } 2763 }
2762 } 2764 }
2763 2765
2766 static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
2767 // Load the spread argument into rbx.
2768 __ movp(rbx, Operand(rsp, kPointerSize));
2769 // Load the map of the spread into r15.
2770 __ movp(r15, FieldOperand(rbx, HeapObject::kMapOffset));
2771 // Load native context into r14.
2772 __ movp(r14, NativeContextOperand());
2773
2774 Label runtime_call, push_args;
2775 // Check that the spread is an array.
2776 __ CmpInstanceType(r15, JS_ARRAY_TYPE);
2777 __ j(not_equal, &runtime_call);
2778
2779 // Check that we have the original ArrayPrototype.
2780 __ movp(rcx, FieldOperand(r15, Map::kPrototypeOffset));
2781 __ cmpp(rcx, ContextOperand(r14, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2782 __ j(not_equal, &runtime_call);
2783
2784 // Check that the ArrayPrototype hasn't been modified in a way that would
2785 // affect iteration.
2786 __ LoadRoot(rcx, Heap::kArrayIteratorProtectorRootIndex);
2787 __ Cmp(FieldOperand(rcx, Cell::kValueOffset),
2788 Smi::FromInt(Isolate::kProtectorValid));
2789 __ j(not_equal, &runtime_call);
2790
2791 // Check that the map of the initial array iterator hasn't changed.
2792 __ movp(rcx,
2793 ContextOperand(r14, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX));
2794 __ movp(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
2795 __ cmpp(rcx, ContextOperand(
2796 r14, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX));
2797 __ j(not_equal, &runtime_call);
2798
2799 // For FastPacked kinds, iteration will have the same effect as simply
2800 // accessing each property in order.
2801 Label no_protector_check;
2802 __ movzxbp(rcx, FieldOperand(r15, Map::kBitField2Offset));
2803 __ DecodeField<Map::ElementsKindBits>(rcx);
2804 __ cmpp(rcx, Immediate(FAST_HOLEY_ELEMENTS));
2805 __ j(above, &runtime_call);
2806 // For non-FastHoley kinds, we can skip the protector check.
2807 __ cmpp(rcx, Immediate(FAST_SMI_ELEMENTS));
2808 __ j(equal, &no_protector_check);
2809 __ cmpp(rcx, Immediate(FAST_ELEMENTS));
2810 __ j(equal, &no_protector_check);
2811 // Check the ArrayProtector cell.
2812 __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex);
2813 __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset),
2814 Smi::FromInt(Isolate::kProtectorValid));
2815 __ j(not_equal, &runtime_call);
2816
2817 __ bind(&no_protector_check);
2818 // Load the FixedArray backing store, but use the length from the array.
2819 __ SmiToInteger32(r9, FieldOperand(rbx, JSArray::kLengthOffset));
2820 __ movp(rbx, FieldOperand(rbx, JSArray::kElementsOffset));
2821 __ jmp(&push_args);
2822
2823 __ bind(&runtime_call);
2824 {
2825 // Call the builtin for the result of the spread.
2826 FrameScope scope(masm, StackFrame::INTERNAL);
2827 __ Push(rdi); // target
2828 __ Push(rdx); // new target
2829 __ Integer32ToSmi(rax, rax);
2830 __ Push(rax); // nargs
2831 __ Push(rbx);
2832 __ CallRuntime(Runtime::kSpreadIterableFixed);
2833 __ movp(rbx, rax);
2834 __ Pop(rax); // nargs
2835 __ SmiToInteger32(rax, rax);
2836 __ Pop(rdx); // new target
2837 __ Pop(rdi); // target
2838 }
2839
2840 {
2841 // Calculate the new nargs including the result of the spread.
2842 __ SmiToInteger32(r9, FieldOperand(rbx, FixedArray::kLengthOffset));
2843
2844 __ bind(&push_args);
2845 // rax += r9 - 1. Subtract 1 for the spread itself.
2846 __ leap(rax, Operand(rax, r9, times_1, -1));
2847
2848 // Pop the return address and spread argument.
2849 __ PopReturnAddressTo(r8);
2850 __ Pop(rcx);
2851 }
2852
2853 // Check for stack overflow.
2854 {
2855 // Check the stack for overflow. We are not trying to catch interruptions
2856 // (i.e. debug break and preemption) here, so check the "real stack limit".
2857 Label done;
2858 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
2859 __ movp(rcx, rsp);
2860 // Make rcx the space we have left. The stack might already be overflowed
2861 // here which will cause rcx to become negative.
2862 __ subp(rcx, kScratchRegister);
2863 __ sarp(rcx, Immediate(kPointerSizeLog2));
2864 // Check if the arguments will overflow the stack.
2865 __ cmpp(rcx, r9);
2866 __ j(greater, &done, Label::kNear); // Signed comparison.
2867 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2868 __ bind(&done);
2869 }
2870
2871 // Put the evaluated spread onto the stack as additional arguments.
2872 {
2873 __ Set(rcx, 0);
2874 Label done, loop;
2875 __ bind(&loop);
2876 __ cmpl(rcx, r9);
2877 __ j(equal, &done, Label::kNear);
2878 __ movp(kScratchRegister, FieldOperand(rbx, rcx, times_pointer_size,
2879 FixedArray::kHeaderSize));
2880 __ Push(kScratchRegister);
2881 __ incl(rcx);
2882 __ jmp(&loop);
2883 __ bind(&done);
2884 __ PushReturnAddressFrom(r8);
2885 }
2886 }
2887
2888 // static
2889 void Builtins::Generate_CallWithSpread(MacroAssembler* masm) {
2890 // ----------- S t a t e -------------
2891 // -- rax : the number of arguments (not including the receiver)
2892 // -- rdi : the target to call (can be any Object)
2893 // -----------------------------------
2894
2895 // CheckSpreadAndPushToStack will push rdx to save it.
2896 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
2897 CheckSpreadAndPushToStack(masm);
2898 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2899 TailCallMode::kDisallow),
2900 RelocInfo::CODE_TARGET);
2901 }
2902
2764 // static 2903 // static
2765 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { 2904 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2766 // ----------- S t a t e ------------- 2905 // ----------- S t a t e -------------
2767 // -- rax : the number of arguments (not including the receiver) 2906 // -- rax : the number of arguments (not including the receiver)
2768 // -- rdx : the new target (checked to be a constructor) 2907 // -- rdx : the new target (checked to be a constructor)
2769 // -- rdi : the constructor to call (checked to be a JSFunction) 2908 // -- rdi : the constructor to call (checked to be a JSFunction)
2770 // ----------------------------------- 2909 // -----------------------------------
2771 __ AssertFunction(rdi); 2910 __ AssertFunction(rdi);
2772 2911
2773 // Calling convention for function specific ConstructStubs require 2912 // Calling convention for function specific ConstructStubs require
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2885 3024
2886 // static 3025 // static
2887 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) { 3026 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2888 // ----------- S t a t e ------------- 3027 // ----------- S t a t e -------------
2889 // -- rax : the number of arguments (not including the receiver) 3028 // -- rax : the number of arguments (not including the receiver)
2890 // -- rdx : the new target (either the same as the constructor or 3029 // -- rdx : the new target (either the same as the constructor or
2891 // the JSFunction on which new was invoked initially) 3030 // the JSFunction on which new was invoked initially)
2892 // -- rdi : the constructor to call (can be any Object) 3031 // -- rdi : the constructor to call (can be any Object)
2893 // ----------------------------------- 3032 // -----------------------------------
2894 3033
2895 // Load the spread argument into rbx. 3034 CheckSpreadAndPushToStack(masm);
2896 __ movp(rbx, Operand(rsp, kPointerSize));
2897 // Load the map of the spread into r15.
2898 __ movp(r15, FieldOperand(rbx, HeapObject::kMapOffset));
2899 // Load native context into r14.
2900 __ movp(r14, NativeContextOperand());
2901
2902 Label runtime_call, push_args;
2903 // Check that the spread is an array.
2904 __ CmpInstanceType(r15, JS_ARRAY_TYPE);
2905 __ j(not_equal, &runtime_call);
2906
2907 // Check that we have the original ArrayPrototype.
2908 __ movp(rcx, FieldOperand(r15, Map::kPrototypeOffset));
2909 __ cmpp(rcx, ContextOperand(r14, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2910 __ j(not_equal, &runtime_call);
2911
2912 // Check that the ArrayPrototype hasn't been modified in a way that would
2913 // affect iteration.
2914 __ LoadRoot(rcx, Heap::kArrayIteratorProtectorRootIndex);
2915 __ Cmp(FieldOperand(rcx, Cell::kValueOffset),
2916 Smi::FromInt(Isolate::kProtectorValid));
2917 __ j(not_equal, &runtime_call);
2918
2919 // Check that the map of the initial array iterator hasn't changed.
2920 __ movp(rcx,
2921 ContextOperand(r14, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX));
2922 __ movp(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
2923 __ cmpp(rcx, ContextOperand(
2924 r14, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX));
2925 __ j(not_equal, &runtime_call);
2926
2927 // For FastPacked kinds, iteration will have the same effect as simply
2928 // accessing each property in order.
2929 Label no_protector_check;
2930 __ movzxbp(rcx, FieldOperand(r15, Map::kBitField2Offset));
2931 __ DecodeField<Map::ElementsKindBits>(rcx);
2932 __ cmpp(rcx, Immediate(FAST_HOLEY_ELEMENTS));
2933 __ j(above, &runtime_call);
2934 // For non-FastHoley kinds, we can skip the protector check.
2935 __ cmpp(rcx, Immediate(FAST_SMI_ELEMENTS));
2936 __ j(equal, &no_protector_check);
2937 __ cmpp(rcx, Immediate(FAST_ELEMENTS));
2938 __ j(equal, &no_protector_check);
2939 // Check the ArrayProtector cell.
2940 __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex);
2941 __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset),
2942 Smi::FromInt(Isolate::kProtectorValid));
2943 __ j(not_equal, &runtime_call);
2944
2945 __ bind(&no_protector_check);
2946 // Load the FixedArray backing store.
2947 __ movp(rbx, FieldOperand(rbx, JSArray::kElementsOffset));
2948 __ jmp(&push_args);
2949
2950 __ bind(&runtime_call);
2951 {
2952 // Call the builtin for the result of the spread.
2953 FrameScope scope(masm, StackFrame::INTERNAL);
2954 __ Push(rdi); // target
2955 __ Push(rdx); // new target
2956 __ Integer32ToSmi(rax, rax);
2957 __ Push(rax); // nargs
2958 __ Push(rbx);
2959 __ CallRuntime(Runtime::kSpreadIterableFixed);
2960 __ movp(rbx, rax);
2961 __ Pop(rax); // nargs
2962 __ SmiToInteger32(rax, rax);
2963 __ Pop(rdx); // new target
2964 __ Pop(rdi); // target
2965 }
2966
2967 __ bind(&push_args);
2968 {
2969 // Pop the return address and spread argument.
2970 __ PopReturnAddressTo(r8);
2971 __ Pop(rcx);
2972
2973 // Calculate the new nargs including the result of the spread.
2974 __ SmiToInteger32(r9, FieldOperand(rbx, FixedArray::kLengthOffset));
2975 // rax += r9 - 1. Subtract 1 for the spread itself.
2976 __ leap(rax, Operand(rax, r9, times_1, -1));
2977 }
2978
2979 // Check for stack overflow.
2980 {
2981 // Check the stack for overflow. We are not trying to catch interruptions
2982 // (i.e. debug break and preemption) here, so check the "real stack limit".
2983 Label done;
2984 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
2985 __ movp(rcx, rsp);
2986 // Make rcx the space we have left. The stack might already be overflowed
2987 // here which will cause rcx to become negative.
2988 __ subp(rcx, kScratchRegister);
2989 __ sarp(rcx, Immediate(kPointerSizeLog2));
2990 // Check if the arguments will overflow the stack.
2991 __ cmpp(rcx, r9);
2992 __ j(greater, &done, Label::kNear); // Signed comparison.
2993 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2994 __ bind(&done);
2995 }
2996
2997 // Put the evaluated spread onto the stack as additional arguments.
2998 {
2999 __ Set(rcx, 0);
3000 Label done, loop;
3001 __ bind(&loop);
3002 __ cmpl(rcx, r9);
3003 __ j(equal, &done, Label::kNear);
3004 __ movp(kScratchRegister, FieldOperand(rbx, rcx, times_pointer_size,
3005 FixedArray::kHeaderSize));
3006 __ Push(kScratchRegister);
3007 __ incl(rcx);
3008 __ jmp(&loop);
3009 __ bind(&done);
3010 __ PushReturnAddressFrom(r8);
3011 }
3012 // Dispatch.
3013 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 3035 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
3014 } 3036 }
3015 3037
3016 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, 3038 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
3017 Register function_template_info, 3039 Register function_template_info,
3018 Register scratch0, Register scratch1, 3040 Register scratch0, Register scratch1,
3019 Register scratch2, 3041 Register scratch2,
3020 Label* receiver_check_failed) { 3042 Label* receiver_check_failed) {
3021 Register signature = scratch0; 3043 Register signature = scratch0;
3022 Register map = scratch1; 3044 Register map = scratch1;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3178 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3200 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3179 Generate_OnStackReplacementHelper(masm, true); 3201 Generate_OnStackReplacementHelper(masm, true);
3180 } 3202 }
3181 3203
3182 #undef __ 3204 #undef __
3183 3205
3184 } // namespace internal 3206 } // namespace internal
3185 } // namespace v8 3207 } // namespace v8
3186 3208
3187 #endif // V8_TARGET_ARCH_X64 3209 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/builtins/s390/builtins-s390.cc ('k') | src/builtins/x87/builtins-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698