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

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

Issue 2571563004: [Turbofan] Implement super calls with spread bytecode in assembly code. (Closed)
Patch Set: MIPS64 port 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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 __ bind(&stack_overflow); 808 __ bind(&stack_overflow);
809 { 809 {
810 __ TailCallRuntime(Runtime::kThrowStackOverflow); 810 __ TailCallRuntime(Runtime::kThrowStackOverflow);
811 // This should be unreachable. 811 // This should be unreachable.
812 __ int3(); 812 __ int3();
813 } 813 }
814 } 814 }
815 815
816 // static 816 // static
817 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 817 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
818 MacroAssembler* masm, CallableType construct_type) { 818 MacroAssembler* masm, PushArgsConstructMode mode) {
819 // ----------- S t a t e ------------- 819 // ----------- S t a t e -------------
820 // -- rax : the number of arguments (not including the receiver) 820 // -- rax : the number of arguments (not including the receiver)
821 // -- rdx : the new target (either the same as the constructor or 821 // -- rdx : the new target (either the same as the constructor or
822 // the JSFunction on which new was invoked initially) 822 // the JSFunction on which new was invoked initially)
823 // -- rdi : the constructor to call (can be any Object) 823 // -- rdi : the constructor to call (can be any Object)
824 // -- rbx : the allocation site feedback if available, undefined otherwise 824 // -- rbx : the allocation site feedback if available, undefined otherwise
825 // -- rcx : the address of the first argument to be pushed. Subsequent 825 // -- rcx : the address of the first argument to be pushed. Subsequent
826 // arguments should be consecutive above this, in the same order as 826 // arguments should be consecutive above this, in the same order as
827 // they are to be pushed onto the stack. 827 // they are to be pushed onto the stack.
828 // ----------------------------------- 828 // -----------------------------------
829 Label stack_overflow; 829 Label stack_overflow;
830 830
831 // Add a stack check before pushing arguments. 831 // Add a stack check before pushing arguments.
832 Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow); 832 Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow);
833 833
834 // Pop return address to allow tail-call after pushing arguments. 834 // Pop return address to allow tail-call after pushing arguments.
835 __ PopReturnAddressTo(kScratchRegister); 835 __ PopReturnAddressTo(kScratchRegister);
836 836
837 // Push slot for the receiver to be constructed. 837 // Push slot for the receiver to be constructed.
838 __ Push(Immediate(0)); 838 __ Push(Immediate(0));
839 839
840 // rcx and r8 will be modified. 840 // rcx and r8 will be modified.
841 Generate_InterpreterPushArgs(masm, rax, rcx, r8); 841 Generate_InterpreterPushArgs(masm, rax, rcx, r8);
842 842
843 // Push return address in preparation for the tail-call. 843 // Push return address in preparation for the tail-call.
844 __ PushReturnAddressFrom(kScratchRegister); 844 __ PushReturnAddressFrom(kScratchRegister);
845 845
846 __ AssertUndefinedOrAllocationSite(rbx); 846 __ AssertUndefinedOrAllocationSite(rbx);
847 if (construct_type == CallableType::kJSFunction) { 847 if (mode == PushArgsConstructMode::kJSFunction) {
848 // 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
849 // context at this point). 849 // context at this point).
850 __ AssertFunction(rdi); 850 __ AssertFunction(rdi);
851 851
852 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 852 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
853 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); 853 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
854 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 854 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
855 // Jump to the constructor function (rax, rbx, rdx passed on). 855 // Jump to the constructor function (rax, rbx, rdx passed on).
856 __ jmp(rcx); 856 __ jmp(rcx);
857 } else if (mode == PushArgsConstructMode::kWithFinalSpread) {
858 // Call the constructor (rax, rdx, rdi passed on).
859 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(),
860 RelocInfo::CODE_TARGET);
857 } else { 861 } else {
858 DCHECK_EQ(construct_type, CallableType::kAny); 862 DCHECK_EQ(PushArgsConstructMode::kOther, mode);
859 // Call the constructor (rax, rdx, rdi passed on). 863 // Call the constructor (rax, rdx, rdi passed on).
860 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 864 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
861 } 865 }
862 866
863 // Throw stack overflow exception. 867 // Throw stack overflow exception.
864 __ bind(&stack_overflow); 868 __ bind(&stack_overflow);
865 { 869 {
866 __ TailCallRuntime(Runtime::kThrowStackOverflow); 870 __ TailCallRuntime(Runtime::kThrowStackOverflow);
867 // This should be unreachable. 871 // This should be unreachable.
868 __ int3(); 872 __ int3();
(...skipping 1997 matching lines...) Expand 10 before | Expand all | Expand 10 after
2866 RelocInfo::CODE_TARGET); 2870 RelocInfo::CODE_TARGET);
2867 } 2871 }
2868 2872
2869 // Called Construct on an Object that doesn't have a [[Construct]] internal 2873 // Called Construct on an Object that doesn't have a [[Construct]] internal
2870 // method. 2874 // method.
2871 __ bind(&non_constructor); 2875 __ bind(&non_constructor);
2872 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(), 2876 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2873 RelocInfo::CODE_TARGET); 2877 RelocInfo::CODE_TARGET);
2874 } 2878 }
2875 2879
2880 // static
2881 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2882 // ----------- S t a t e -------------
2883 // -- rax : the number of arguments (not including the receiver)
2884 // -- rdx : the new target (either the same as the constructor or
2885 // the JSFunction on which new was invoked initially)
2886 // -- rdi : the constructor to call (can be any Object)
2887 // -----------------------------------
2888
2889 // Load the spread argument into rbx.
2890 __ movp(rbx, Operand(rsp, kPointerSize));
2891 // Load the map of the spread into r15.
2892 __ movp(r15, FieldOperand(rbx, HeapObject::kMapOffset));
2893 // Load native context into r14.
2894 __ movp(r14, NativeContextOperand());
2895
2896 Label runtime_call, push_args;
2897 // Check that the spread is an array.
2898 __ CmpInstanceType(r15, JS_ARRAY_TYPE);
2899 __ j(not_equal, &runtime_call);
2900
2901 // Check that we have the original ArrayPrototype.
2902 __ movp(rcx, FieldOperand(r15, Map::kPrototypeOffset));
2903 __ cmpp(rcx, ContextOperand(r14, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2904 __ j(not_equal, &runtime_call);
2905
2906 // Check that the ArrayPrototype hasn't been modified in a way that would
2907 // affect iteration.
2908 __ LoadRoot(rcx, Heap::kArrayIteratorProtectorRootIndex);
2909 __ Cmp(FieldOperand(rcx, Cell::kValueOffset),
2910 Smi::FromInt(Isolate::kProtectorValid));
2911 __ j(not_equal, &runtime_call);
2912
2913 // Check that the map of the initial array iterator hasn't changed.
2914 __ movp(rcx,
2915 ContextOperand(r14, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX));
2916 __ movp(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
2917 __ cmpp(rcx, ContextOperand(
2918 r14, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX));
2919 __ j(not_equal, &runtime_call);
2920
2921 // For FastPacked kinds, iteration will have the same effect as simply
2922 // accessing each property in order.
2923 Label no_protector_check;
2924 __ movzxbp(rcx, FieldOperand(r15, Map::kBitField2Offset));
2925 __ DecodeField<Map::ElementsKindBits>(rcx);
2926 __ cmpp(rcx, Immediate(LAST_FAST_ELEMENTS_KIND));
2927 __ j(above, &runtime_call);
2928 // For non-FastHoley kinds, we can skip the protector check.
2929 __ cmpp(rcx, Immediate(FAST_SMI_ELEMENTS));
2930 __ j(equal, &no_protector_check);
2931 __ cmpp(rcx, Immediate(FAST_ELEMENTS));
2932 __ j(equal, &no_protector_check);
2933 __ cmpp(rcx, Immediate(FAST_DOUBLE_ELEMENTS));
2934 __ j(equal, &no_protector_check);
2935 // Check the ArrayProtector cell.
2936 __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex);
2937 __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset),
2938 Smi::FromInt(Isolate::kProtectorValid));
2939 __ j(not_equal, &runtime_call);
2940
2941 __ bind(&no_protector_check);
2942 // Load the FixedArray backing store.
2943 __ movp(rbx, FieldOperand(rbx, JSArray::kElementsOffset));
2944 __ jmp(&push_args);
2945
2946 __ bind(&runtime_call);
2947 {
2948 // Call the builtin for the result of the spread.
2949 FrameScope scope(masm, StackFrame::INTERNAL);
2950 __ Push(rdi); // target
2951 __ Push(rdx); // new target
2952 __ Integer32ToSmi(rax, rax);
2953 __ Push(rax); // nargs
2954 __ Push(rbx);
2955 __ CallRuntime(Runtime::kSpreadIterableFixed);
2956 __ movp(rbx, rax);
2957 __ Pop(rax); // nargs
2958 __ SmiToInteger32(rax, rax);
2959 __ Pop(rdx); // new target
2960 __ Pop(rdi); // target
2961 }
2962
2963 __ bind(&push_args);
2964 {
2965 // Pop the return address and spread argument.
2966 __ PopReturnAddressTo(r8);
2967 __ Pop(rcx);
2968
2969 // Calculate the new nargs including the result of the spread.
2970 __ SmiToInteger32(r9, FieldOperand(rbx, FixedArray::kLengthOffset));
2971 // rax += r9 - 1. Subtract 1 for the spread itself.
2972 __ leap(rax, Operand(rax, r9, times_1, -1));
2973 }
2974
2975 // Check for stack overflow.
2976 {
2977 // Check the stack for overflow. We are not trying to catch interruptions
2978 // (i.e. debug break and preemption) here, so check the "real stack limit".
2979 Label done;
2980 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
2981 __ movp(rcx, rsp);
2982 // Make rcx the space we have left. The stack might already be overflowed
2983 // here which will cause rcx to become negative.
2984 __ subp(rcx, kScratchRegister);
2985 __ sarp(rcx, Immediate(kPointerSizeLog2));
2986 // Check if the arguments will overflow the stack.
2987 __ cmpp(rcx, r9);
2988 __ j(greater, &done, Label::kNear); // Signed comparison.
2989 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2990 __ bind(&done);
2991 }
2992
2993 // Put the evaluated spread onto the stack as additional arguments.
2994 {
2995 __ Set(rcx, 0);
2996 Label done, loop;
2997 __ bind(&loop);
2998 __ cmpl(rcx, r9);
2999 __ j(equal, &done, Label::kNear);
3000 __ movp(kScratchRegister, FieldOperand(rbx, rcx, times_pointer_size,
3001 FixedArray::kHeaderSize));
3002 __ Push(kScratchRegister);
3003 __ incl(rcx);
3004 __ jmp(&loop);
3005 __ bind(&done);
3006 __ PushReturnAddressFrom(r8);
3007 }
3008 // Dispatch.
3009 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
3010 }
3011
2876 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, 3012 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
2877 Register function_template_info, 3013 Register function_template_info,
2878 Register scratch0, Register scratch1, 3014 Register scratch0, Register scratch1,
2879 Register scratch2, 3015 Register scratch2,
2880 Label* receiver_check_failed) { 3016 Label* receiver_check_failed) {
2881 Register signature = scratch0; 3017 Register signature = scratch0;
2882 Register map = scratch1; 3018 Register map = scratch1;
2883 Register constructor = scratch2; 3019 Register constructor = scratch2;
2884 3020
2885 // If there is no signature, return the holder. 3021 // If there is no signature, return the holder.
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3038 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3174 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3039 Generate_OnStackReplacementHelper(masm, true); 3175 Generate_OnStackReplacementHelper(masm, true);
3040 } 3176 }
3041 3177
3042 #undef __ 3178 #undef __
3043 3179
3044 } // namespace internal 3180 } // namespace internal
3045 } // namespace v8 3181 } // namespace v8
3046 3182
3047 #endif // V8_TARGET_ARCH_X64 3183 #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