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

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: Rebase on master Created 4 years 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/builtins.h ('k') | src/code-factory.h » ('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 2865 matching lines...) Expand 10 before | Expand all | Expand 10 after
2876 RelocInfo::CODE_TARGET); 2876 RelocInfo::CODE_TARGET);
2877 } 2877 }
2878 2878
2879 // Called Construct on an Object that doesn't have a [[Construct]] internal 2879 // Called Construct on an Object that doesn't have a [[Construct]] internal
2880 // method. 2880 // method.
2881 __ bind(&non_constructor); 2881 __ bind(&non_constructor);
2882 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(), 2882 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2883 RelocInfo::CODE_TARGET); 2883 RelocInfo::CODE_TARGET);
2884 } 2884 }
2885 2885
2886 // static
2887 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2888 // ----------- S t a t e -------------
2889 // -- rax : the number of arguments (not including the receiver)
2890 // -- rdx : the new target (either the same as the constructor or
2891 // the JSFunction on which new was invoked initially)
2892 // -- rdi : the constructor to call (can be any Object)
2893 // -----------------------------------
2894
2895 // Make sure the target is actually a constructor.
2896 Label target_not_constructor;
Benedikt Meurer 2016/12/15 11:59:52 These checks must not be performed before the eval
petermarshall 2016/12/15 13:37:27 Yep cool
2897 __ JumpIfSmi(rdi, &target_not_constructor, Label::kFar);
2898 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset));
2899 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
2900 Immediate(1 << Map::kIsConstructor));
2901 __ j(zero, &target_not_constructor, Label::kFar);
2902
2903 // Make sure the new target is actually a constructor.
2904 Label new_target_not_constructor;
Benedikt Meurer 2016/12/15 11:59:52 Same for new.target
2905 __ JumpIfSmi(rdx, &new_target_not_constructor, Label::kFar);
2906 __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
2907 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
2908 Immediate(1 << Map::kIsConstructor));
2909 __ j(zero, &new_target_not_constructor, Label::kFar);
2910
2911 // Load the spread argument.
2912 __ movp(rbx, Operand(rsp, kPointerSize));
2913 {
2914 // Call the builtin for the result of the spread.
2915 FrameScope scope(masm, StackFrame::INTERNAL);
2916 __ Push(rdi); // target
2917 __ Push(rdx); // new target
2918 __ Integer32ToSmi(rax, rax);
2919 __ Push(rax); // nargs
2920 __ Push(rbx);
2921 __ CallRuntime(Runtime::kSpreadIterablePrepareFixed);
2922 __ movp(rbx, rax);
2923 __ Pop(rax); // nargs
2924 __ SmiToInteger32(rax, rax);
2925 __ Pop(rdx); // new target
2926 __ Pop(rdi); // target
2927 }
2928
2929 {
2930 // Pop the return address and spread argument.
2931 __ PopReturnAddressTo(r8);
2932 __ Pop(rcx);
2933
2934 // Calculate the new nargs including the result of the spread.
2935 __ SmiToInteger32(r9, FieldOperand(rbx, FixedArray::kLengthOffset));
2936 __ addp(rax, r9);
Benedikt Meurer 2016/12/15 11:59:52 You can combine these addp and subp into a single
petermarshall 2016/12/15 13:37:27 I always thought leap was a funny instruction name
2937 __ subp(rax, Immediate(1)); // Subtract 1 for the spread itself.
2938 }
2939
2940 // Check for stack overflow.
2941 {
2942 // Check the stack for overflow. We are not trying to catch interruptions
2943 // (i.e. debug break and preemption) here, so check the "real stack limit".
2944 Label done;
2945 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
2946 __ movp(rcx, rsp);
2947 // Make rcx the space we have left. The stack might already be overflowed
2948 // here which will cause rcx to become negative.
2949 __ subp(rcx, kScratchRegister);
2950 __ sarp(rcx, Immediate(kPointerSizeLog2));
2951 // Check if the arguments will overflow the stack.
2952 __ cmpp(rcx, r9);
2953 __ j(greater, &done, Label::kNear); // Signed comparison.
2954 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2955 __ bind(&done);
2956 }
2957
2958 // Put the evaluated spread onto the stack as additional arguments.
2959 {
2960 __ Set(rcx, 0);
2961 Label done, loop;
2962 __ bind(&loop);
2963 __ cmpl(rcx, r9);
2964 __ j(equal, &done, Label::kNear);
2965 __ movp(kScratchRegister, FieldOperand(rbx, rcx, times_pointer_size,
2966 FixedArray::kHeaderSize));
2967 __ Push(kScratchRegister);
2968 __ incl(rcx);
2969 __ jmp(&loop);
2970 __ bind(&done);
2971 __ PushReturnAddressFrom(r8);
2972 }
2973
2974 // Dispatch
2975 { __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); }
2976
2977 // The target is not a constructor, throw an appropriate TypeError.
2978 __ bind(&target_not_constructor);
2979 {
2980 StackArgumentsAccessor args(rsp, 0);
2981 __ movp(args.GetReceiverOperand(), rdi);
2982 __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
2983 }
2984
2985 // The new.target is not a constructor, throw an appropriate TypeError.
2986 __ bind(&new_target_not_constructor);
2987 {
2988 StackArgumentsAccessor args(rsp, 0);
2989 __ movp(args.GetReceiverOperand(), rdx);
2990 __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
2991 }
2992 }
2993
2886 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, 2994 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
2887 Register function_template_info, 2995 Register function_template_info,
2888 Register scratch0, Register scratch1, 2996 Register scratch0, Register scratch1,
2889 Register scratch2, 2997 Register scratch2,
2890 Label* receiver_check_failed) { 2998 Label* receiver_check_failed) {
2891 Register signature = scratch0; 2999 Register signature = scratch0;
2892 Register map = scratch1; 3000 Register map = scratch1;
2893 Register constructor = scratch2; 3001 Register constructor = scratch2;
2894 3002
2895 // If there is no signature, return the holder. 3003 // If there is no signature, return the holder.
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3156 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3049 Generate_OnStackReplacementHelper(masm, true); 3157 Generate_OnStackReplacementHelper(masm, true);
3050 } 3158 }
3051 3159
3052 #undef __ 3160 #undef __
3053 3161
3054 } // namespace internal 3162 } // namespace internal
3055 } // namespace v8 3163 } // namespace v8
3056 3164
3057 #endif // V8_TARGET_ARCH_X64 3165 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698