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

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

Issue 2655233002: [turbofan] Introduce JSCallForwardVarargs operator. (Closed)
Patch Set: Fix formatting. 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/mips64/builtins-mips64.cc ('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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 __ bind(&switch_to_different_code_kind); 713 __ bind(&switch_to_different_code_kind);
714 __ leave(); // Leave the frame so we can tail call. 714 __ leave(); // Leave the frame so we can tail call.
715 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 715 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
716 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); 716 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset));
717 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 717 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
718 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); 718 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx);
719 __ RecordWriteCodeEntryField(rdi, rcx, r15); 719 __ RecordWriteCodeEntryField(rdi, rcx, r15);
720 __ jmp(rcx); 720 __ jmp(rcx);
721 } 721 }
722 722
723 static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, 723 static void Generate_StackOverflowCheck(
724 Register scratch1, Register scratch2, 724 MacroAssembler* masm, Register num_args, Register scratch,
725 Label* stack_overflow) { 725 Label* stack_overflow,
726 Label::Distance stack_overflow_distance = Label::kFar) {
726 // Check the stack for overflow. We are not trying to catch 727 // Check the stack for overflow. We are not trying to catch
727 // interruptions (e.g. debug break and preemption) here, so the "real stack 728 // interruptions (e.g. debug break and preemption) here, so the "real stack
728 // limit" is checked. 729 // limit" is checked.
729 __ LoadRoot(scratch1, Heap::kRealStackLimitRootIndex); 730 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
730 __ movp(scratch2, rsp); 731 __ movp(scratch, rsp);
731 // Make scratch2 the space we have left. The stack might already be overflowed 732 // Make scratch the space we have left. The stack might already be overflowed
732 // here which will cause scratch2 to become negative. 733 // here which will cause scratch to become negative.
733 __ subp(scratch2, scratch1); 734 __ subp(scratch, kScratchRegister);
734 // Make scratch1 the space we need for the array when it is unrolled onto the 735 __ sarp(scratch, Immediate(kPointerSizeLog2));
735 // stack.
736 __ movp(scratch1, num_args);
737 __ shlp(scratch1, Immediate(kPointerSizeLog2));
738 // Check if the arguments will overflow the stack. 736 // Check if the arguments will overflow the stack.
739 __ cmpp(scratch2, scratch1); 737 __ cmpp(scratch, num_args);
740 __ j(less_equal, stack_overflow); // Signed comparison. 738 // Signed comparison.
739 __ j(less_equal, stack_overflow, stack_overflow_distance);
741 } 740 }
742 741
743 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 742 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
744 Register num_args, 743 Register num_args,
745 Register start_address, 744 Register start_address,
746 Register scratch) { 745 Register scratch) {
747 // Find the address of the last argument. 746 // Find the address of the last argument.
748 __ Move(scratch, num_args); 747 __ Move(scratch, num_args);
749 __ shlp(scratch, Immediate(kPointerSizeLog2)); 748 __ shlp(scratch, Immediate(kPointerSizeLog2));
750 __ negp(scratch); 749 __ negp(scratch);
(...skipping 21 matching lines...) Expand all
772 // they are to be pushed onto the stack. 771 // they are to be pushed onto the stack.
773 // -- rdi : the target to call (can be any Object). 772 // -- rdi : the target to call (can be any Object).
774 // ----------------------------------- 773 // -----------------------------------
775 Label stack_overflow; 774 Label stack_overflow;
776 775
777 // Number of values to be pushed. 776 // Number of values to be pushed.
778 __ Move(rcx, rax); 777 __ Move(rcx, rax);
779 __ addp(rcx, Immediate(1)); // Add one for receiver. 778 __ addp(rcx, Immediate(1)); // Add one for receiver.
780 779
781 // Add a stack check before pushing arguments. 780 // Add a stack check before pushing arguments.
782 Generate_StackOverflowCheck(masm, rcx, rdx, r8, &stack_overflow); 781 Generate_StackOverflowCheck(masm, rcx, rdx, &stack_overflow);
783 782
784 // Pop return address to allow tail-call after pushing arguments. 783 // Pop return address to allow tail-call after pushing arguments.
785 __ PopReturnAddressTo(kScratchRegister); 784 __ PopReturnAddressTo(kScratchRegister);
786 785
787 // rbx and rdx will be modified. 786 // rbx and rdx will be modified.
788 Generate_InterpreterPushArgs(masm, rcx, rbx, rdx); 787 Generate_InterpreterPushArgs(masm, rcx, rbx, rdx);
789 788
790 // Call the target. 789 // Call the target.
791 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. 790 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
792 791
(...skipping 28 matching lines...) Expand all
821 // the JSFunction on which new was invoked initially) 820 // the JSFunction on which new was invoked initially)
822 // -- rdi : the constructor to call (can be any Object) 821 // -- rdi : the constructor to call (can be any Object)
823 // -- rbx : the allocation site feedback if available, undefined otherwise 822 // -- rbx : the allocation site feedback if available, undefined otherwise
824 // -- rcx : the address of the first argument to be pushed. Subsequent 823 // -- rcx : the address of the first argument to be pushed. Subsequent
825 // arguments should be consecutive above this, in the same order as 824 // arguments should be consecutive above this, in the same order as
826 // they are to be pushed onto the stack. 825 // they are to be pushed onto the stack.
827 // ----------------------------------- 826 // -----------------------------------
828 Label stack_overflow; 827 Label stack_overflow;
829 828
830 // Add a stack check before pushing arguments. 829 // Add a stack check before pushing arguments.
831 Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow); 830 Generate_StackOverflowCheck(masm, rax, r8, &stack_overflow);
832 831
833 // Pop return address to allow tail-call after pushing arguments. 832 // Pop return address to allow tail-call after pushing arguments.
834 __ PopReturnAddressTo(kScratchRegister); 833 __ PopReturnAddressTo(kScratchRegister);
835 834
836 // Push slot for the receiver to be constructed. 835 // Push slot for the receiver to be constructed.
837 __ Push(Immediate(0)); 836 __ Push(Immediate(0));
838 837
839 // rcx and r8 will be modified. 838 // rcx and r8 will be modified.
840 Generate_InterpreterPushArgs(masm, rax, rcx, r8); 839 Generate_InterpreterPushArgs(masm, rax, rcx, r8);
841 840
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 // arguments should be consecutive above this, in the same order as 882 // arguments should be consecutive above this, in the same order as
884 // they are to be pushed onto the stack. 883 // they are to be pushed onto the stack.
885 // ----------------------------------- 884 // -----------------------------------
886 Label stack_overflow; 885 Label stack_overflow;
887 886
888 // Number of values to be pushed. 887 // Number of values to be pushed.
889 __ Move(r8, rax); 888 __ Move(r8, rax);
890 __ addp(r8, Immediate(1)); // Add one for receiver. 889 __ addp(r8, Immediate(1)); // Add one for receiver.
891 890
892 // Add a stack check before pushing arguments. 891 // Add a stack check before pushing arguments.
893 Generate_StackOverflowCheck(masm, r8, rdi, r9, &stack_overflow); 892 Generate_StackOverflowCheck(masm, r8, rdi, &stack_overflow);
894 893
895 // Pop return address to allow tail-call after pushing arguments. 894 // Pop return address to allow tail-call after pushing arguments.
896 __ PopReturnAddressTo(kScratchRegister); 895 __ PopReturnAddressTo(kScratchRegister);
897 896
898 // rcx and rdi will be modified. 897 // rcx and rdi will be modified.
899 Generate_InterpreterPushArgs(masm, r8, rcx, rdi); 898 Generate_InterpreterPushArgs(masm, r8, rcx, rdi);
900 899
901 // Push return address in preparation for the tail-call. 900 // Push return address in preparation for the tail-call.
902 __ PushReturnAddressFrom(kScratchRegister); 901 __ PushReturnAddressFrom(kScratchRegister);
903 902
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2140 Label enough, too_few; 2139 Label enough, too_few;
2141 __ cmpp(rax, rbx); 2140 __ cmpp(rax, rbx);
2142 __ j(less, &too_few); 2141 __ j(less, &too_few);
2143 __ cmpp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 2142 __ cmpp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
2144 __ j(equal, &dont_adapt_arguments); 2143 __ j(equal, &dont_adapt_arguments);
2145 2144
2146 { // Enough parameters: Actual >= expected. 2145 { // Enough parameters: Actual >= expected.
2147 __ bind(&enough); 2146 __ bind(&enough);
2148 EnterArgumentsAdaptorFrame(masm); 2147 EnterArgumentsAdaptorFrame(masm);
2149 // The registers rcx and r8 will be modified. The register rbx is only read. 2148 // The registers rcx and r8 will be modified. The register rbx is only read.
2150 Generate_StackOverflowCheck(masm, rbx, rcx, r8, &stack_overflow); 2149 Generate_StackOverflowCheck(masm, rbx, rcx, &stack_overflow);
2151 2150
2152 // Copy receiver and all expected arguments. 2151 // Copy receiver and all expected arguments.
2153 const int offset = StandardFrameConstants::kCallerSPOffset; 2152 const int offset = StandardFrameConstants::kCallerSPOffset;
2154 __ leap(rax, Operand(rbp, rax, times_pointer_size, offset)); 2153 __ leap(rax, Operand(rbp, rax, times_pointer_size, offset));
2155 __ Set(r8, -1); // account for receiver 2154 __ Set(r8, -1); // account for receiver
2156 2155
2157 Label copy; 2156 Label copy;
2158 __ bind(&copy); 2157 __ bind(&copy);
2159 __ incp(r8); 2158 __ incp(r8);
2160 __ Push(Operand(rax, 0)); 2159 __ Push(Operand(rax, 0));
2161 __ subp(rax, Immediate(kPointerSize)); 2160 __ subp(rax, Immediate(kPointerSize));
2162 __ cmpp(r8, rbx); 2161 __ cmpp(r8, rbx);
2163 __ j(less, &copy); 2162 __ j(less, &copy);
2164 __ jmp(&invoke); 2163 __ jmp(&invoke);
2165 } 2164 }
2166 2165
2167 { // Too few parameters: Actual < expected. 2166 { // Too few parameters: Actual < expected.
2168 __ bind(&too_few); 2167 __ bind(&too_few);
2169 2168
2170 EnterArgumentsAdaptorFrame(masm); 2169 EnterArgumentsAdaptorFrame(masm);
2171 // The registers rcx and r8 will be modified. The register rbx is only read. 2170 // The registers rcx and r8 will be modified. The register rbx is only read.
2172 Generate_StackOverflowCheck(masm, rbx, rcx, r8, &stack_overflow); 2171 Generate_StackOverflowCheck(masm, rbx, rcx, &stack_overflow);
2173 2172
2174 // Copy receiver and all actual arguments. 2173 // Copy receiver and all actual arguments.
2175 const int offset = StandardFrameConstants::kCallerSPOffset; 2174 const int offset = StandardFrameConstants::kCallerSPOffset;
2176 __ leap(rdi, Operand(rbp, rax, times_pointer_size, offset)); 2175 __ leap(rdi, Operand(rbp, rax, times_pointer_size, offset));
2177 __ Set(r8, -1); // account for receiver 2176 __ Set(r8, -1); // account for receiver
2178 2177
2179 Label copy; 2178 Label copy;
2180 __ bind(&copy); 2179 __ bind(&copy);
2181 __ incp(r8); 2180 __ incp(r8);
2182 __ Push(Operand(rdi, 0)); 2181 __ Push(Operand(rdi, 0));
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 } 2368 }
2370 2369
2371 // Dispatch to Call or Construct depending on whether new.target is undefined. 2370 // Dispatch to Call or Construct depending on whether new.target is undefined.
2372 { 2371 {
2373 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); 2372 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
2374 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 2373 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2375 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2374 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2376 } 2375 }
2377 } 2376 }
2378 2377
2378 // static
2379 void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm,
2380 Handle<Code> code) {
2381 // ----------- S t a t e -------------
2382 // -- rdi : the target to call (can be any Object)
2383 // -- rcx : start index (to support rest parameters)
2384 // -- rsp[0] : return address.
2385 // -- rsp[8] : thisArgument
2386 // -----------------------------------
2387
2388 // Check if we have an arguments adaptor frame below the function frame.
2389 Label arguments_adaptor, arguments_done;
2390 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2391 __ Cmp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset),
2392 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2393 __ j(equal, &arguments_adaptor, Label::kNear);
2394 {
2395 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
2396 __ movp(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
2397 __ LoadSharedFunctionInfoSpecialField(
2398 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset);
2399 __ movp(rbx, rbp);
2400 }
2401 __ jmp(&arguments_done, Label::kNear);
2402 __ bind(&arguments_adaptor);
2403 {
2404 __ SmiToInteger32(
2405 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
2406 }
2407 __ bind(&arguments_done);
2408
2409 Label stack_empty, stack_done, stack_overflow;
2410 __ subl(rax, rcx);
2411 __ j(less_equal, &stack_empty);
2412 {
2413 // Check for stack overflow.
2414 Generate_StackOverflowCheck(masm, rax, rcx, &stack_overflow, Label::kNear);
2415
2416 // Forward the arguments from the caller frame.
2417 {
2418 Label loop;
2419 __ movl(rcx, rax);
2420 __ Pop(r8);
2421 __ bind(&loop);
2422 {
2423 StackArgumentsAccessor args(rbx, rcx, ARGUMENTS_DONT_CONTAIN_RECEIVER);
2424 __ Push(args.GetArgumentOperand(0));
2425 __ decl(rcx);
2426 __ j(not_zero, &loop);
2427 }
2428 __ Push(r8);
2429 }
2430 }
2431 __ jmp(&stack_done, Label::kNear);
2432 __ bind(&stack_overflow);
2433 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2434 __ bind(&stack_empty);
2435 {
2436 // We just pass the receiver, which is already on the stack.
2437 __ Set(rax, 0);
2438 }
2439 __ bind(&stack_done);
2440
2441 __ Jump(code, RelocInfo::CODE_TARGET);
2442 }
2443
2379 namespace { 2444 namespace {
2380 2445
2381 // Drops top JavaScript frame and an arguments adaptor frame below it (if 2446 // Drops top JavaScript frame and an arguments adaptor frame below it (if
2382 // present) preserving all the arguments prepared for current call. 2447 // present) preserving all the arguments prepared for current call.
2383 // Does nothing if debugger is currently active. 2448 // Does nothing if debugger is currently active.
2384 // ES6 14.6.3. PrepareForTailCall 2449 // ES6 14.6.3. PrepareForTailCall
2385 // 2450 //
2386 // Stack structure for the function g() tail calling f(): 2451 // Stack structure for the function g() tail calling f():
2387 // 2452 //
2388 // ------- Caller frame: ------- 2453 // ------- Caller frame: -------
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3265 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3201 Generate_OnStackReplacementHelper(masm, true); 3266 Generate_OnStackReplacementHelper(masm, true);
3202 } 3267 }
3203 3268
3204 #undef __ 3269 #undef __
3205 3270
3206 } // namespace internal 3271 } // namespace internal
3207 } // namespace v8 3272 } // namespace v8
3208 3273
3209 #endif // V8_TARGET_ARCH_X64 3274 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/builtins/mips64/builtins-mips64.cc ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698