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

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

Issue 2335513004: [Interpreter] Adds stackcheck in InterpreterPushArgsAndCall/Construct builtins. (Closed)
Patch Set: fix for ia32 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
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 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 // Push function as argument and compile for baseline. 775 // Push function as argument and compile for baseline.
776 __ Push(rdi); 776 __ Push(rdi);
777 __ CallRuntime(Runtime::kCompileBaseline); 777 __ CallRuntime(Runtime::kCompileBaseline);
778 778
779 // Restore return value. 779 // Restore return value.
780 __ Pop(rax); 780 __ Pop(rax);
781 } 781 }
782 __ ret(0); 782 __ ret(0);
783 } 783 }
784 784
785 static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
786 Register scratch1, Register scratch2,
787 Label* stack_overflow) {
788 // Check the stack for overflow. We are not trying to catch
789 // interruptions (e.g. debug break and preemption) here, so the "real stack
790 // limit" is checked.
791 __ LoadRoot(scratch1, Heap::kRealStackLimitRootIndex);
792 __ movp(scratch2, rsp);
793 // Make scratch2 the space we have left. The stack might already be overflowed
794 // here which will cause scratch2 to become negative.
795 __ subp(scratch2, scratch1);
796 // Make scratch1 the space we need for the array when it is unrolled onto the
797 // stack.
798 __ movp(scratch1, num_args);
799 __ shlp(scratch1, Immediate(kPointerSizeLog2));
800 // Check if the arguments will overflow the stack.
801 __ cmpp(scratch2, scratch1);
802 __ j(less_equal, stack_overflow); // Signed comparison.
803 }
804
785 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 805 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
786 Register num_args, 806 Register num_args,
787 Register start_address, 807 Register start_address,
788 Register scratch) { 808 Register scratch, Register scratch1) {
rmcilroy 2016/09/12 14:43:17 You don't use scratch1 here. (if you do need it, s
mythria 2016/09/13 09:53:33 Thanks, I forgot to remove scratch1. Done.
789 // Find the address of the last argument. 809 // Find the address of the last argument.
790 __ Move(scratch, num_args); 810 __ Move(scratch, num_args);
791 __ shlp(scratch, Immediate(kPointerSizeLog2)); 811 __ shlp(scratch, Immediate(kPointerSizeLog2));
792 __ negp(scratch); 812 __ negp(scratch);
793 __ addp(scratch, start_address); 813 __ addp(scratch, start_address);
794 814
795 // TODO(mythria): Add a stack check before pushing arguments.
796 // Push the arguments. 815 // Push the arguments.
797 Label loop_header, loop_check; 816 Label loop_header, loop_check;
798 __ j(always, &loop_check); 817 __ j(always, &loop_check);
799 __ bind(&loop_header); 818 __ bind(&loop_header);
800 __ Push(Operand(start_address, 0)); 819 __ Push(Operand(start_address, 0));
801 __ subp(start_address, Immediate(kPointerSize)); 820 __ subp(start_address, Immediate(kPointerSize));
802 __ bind(&loop_check); 821 __ bind(&loop_check);
803 __ cmpp(start_address, scratch); 822 __ cmpp(start_address, scratch);
804 __ j(greater, &loop_header, Label::kNear); 823 __ j(greater, &loop_header, Label::kNear);
805 } 824 }
806 825
807 // static 826 // static
808 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 827 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
809 MacroAssembler* masm, TailCallMode tail_call_mode, 828 MacroAssembler* masm, TailCallMode tail_call_mode,
810 CallableType function_type) { 829 CallableType function_type) {
811 // ----------- S t a t e ------------- 830 // ----------- S t a t e -------------
812 // -- rax : the number of arguments (not including the receiver) 831 // -- rax : the number of arguments (not including the receiver)
813 // -- rbx : the address of the first argument to be pushed. Subsequent 832 // -- rbx : the address of the first argument to be pushed. Subsequent
814 // arguments should be consecutive above this, in the same order as 833 // arguments should be consecutive above this, in the same order as
815 // they are to be pushed onto the stack. 834 // they are to be pushed onto the stack.
816 // -- rdi : the target to call (can be any Object). 835 // -- rdi : the target to call (can be any Object).
817 // ----------------------------------- 836 // -----------------------------------
818 837 Label stack_overflow;
819 // Pop return address to allow tail-call after pushing arguments.
820 __ PopReturnAddressTo(kScratchRegister);
821 838
822 // Number of values to be pushed. 839 // Number of values to be pushed.
823 __ Move(rcx, rax); 840 __ Move(rcx, rax);
824 __ addp(rcx, Immediate(1)); // Add one for receiver. 841 __ addp(rcx, Immediate(1)); // Add one for receiver.
825 842
843 // Add a stack check before pushing arguments.
844 Generate_StackOverflowCheck(masm, rcx, rdx, r8, &stack_overflow);
845
846 // Pop return address to allow tail-call after pushing arguments.
847 __ PopReturnAddressTo(kScratchRegister);
848
826 // rbx and rdx will be modified. 849 // rbx and rdx will be modified.
827 Generate_InterpreterPushArgs(masm, rcx, rbx, rdx); 850 Generate_InterpreterPushArgs(masm, rcx, rbx, rdx, r8);
828 851
829 // Call the target. 852 // Call the target.
830 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. 853 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
831 854
832 if (function_type == CallableType::kJSFunction) { 855 if (function_type == CallableType::kJSFunction) {
833 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, 856 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
834 tail_call_mode), 857 tail_call_mode),
835 RelocInfo::CODE_TARGET); 858 RelocInfo::CODE_TARGET);
836 } else { 859 } else {
837 DCHECK_EQ(function_type, CallableType::kAny); 860 DCHECK_EQ(function_type, CallableType::kAny);
838 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 861 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
839 tail_call_mode), 862 tail_call_mode),
840 RelocInfo::CODE_TARGET); 863 RelocInfo::CODE_TARGET);
841 } 864 }
865
866 // Throw stack overflow exception.
867 __ bind(&stack_overflow);
868 {
869 __ TailCallRuntime(Runtime::kThrowStackOverflow);
870 __ int3();
871 }
842 } 872 }
843 873
844 // static 874 // static
845 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 875 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
846 MacroAssembler* masm, CallableType construct_type) { 876 MacroAssembler* masm, CallableType construct_type) {
847 // ----------- S t a t e ------------- 877 // ----------- S t a t e -------------
848 // -- rax : the number of arguments (not including the receiver) 878 // -- rax : the number of arguments (not including the receiver)
849 // -- rdx : the new target (either the same as the constructor or 879 // -- rdx : the new target (either the same as the constructor or
850 // the JSFunction on which new was invoked initially) 880 // the JSFunction on which new was invoked initially)
851 // -- rdi : the constructor to call (can be any Object) 881 // -- rdi : the constructor to call (can be any Object)
852 // -- rbx : the allocation site feedback if available, undefined otherwise 882 // -- rbx : the allocation site feedback if available, undefined otherwise
853 // -- rcx : the address of the first argument to be pushed. Subsequent 883 // -- rcx : the address of the first argument to be pushed. Subsequent
854 // arguments should be consecutive above this, in the same order as 884 // arguments should be consecutive above this, in the same order as
855 // they are to be pushed onto the stack. 885 // they are to be pushed onto the stack.
856 // ----------------------------------- 886 // -----------------------------------
887 Label stack_overflow;
888
889 // Add a stack check before pushing arguments.
890 Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow);
857 891
858 // Pop return address to allow tail-call after pushing arguments. 892 // Pop return address to allow tail-call after pushing arguments.
859 __ PopReturnAddressTo(kScratchRegister); 893 __ PopReturnAddressTo(kScratchRegister);
860 894
861 // Push slot for the receiver to be constructed. 895 // Push slot for the receiver to be constructed.
862 __ Push(Immediate(0)); 896 __ Push(Immediate(0));
863 897
864 // rcx and r8 will be modified. 898 // rcx and r8 will be modified.
865 Generate_InterpreterPushArgs(masm, rax, rcx, r8); 899 Generate_InterpreterPushArgs(masm, rax, rcx, r8, r9);
866 900
867 // Push return address in preparation for the tail-call. 901 // Push return address in preparation for the tail-call.
868 __ PushReturnAddressFrom(kScratchRegister); 902 __ PushReturnAddressFrom(kScratchRegister);
869 903
870 __ AssertUndefinedOrAllocationSite(rbx); 904 __ AssertUndefinedOrAllocationSite(rbx);
871 if (construct_type == CallableType::kJSFunction) { 905 if (construct_type == CallableType::kJSFunction) {
872 // Tail call to the function-specific construct stub (still in the caller 906 // Tail call to the function-specific construct stub (still in the caller
873 // context at this point). 907 // context at this point).
874 __ AssertFunction(rdi); 908 __ AssertFunction(rdi);
875 909
876 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 910 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
877 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); 911 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
878 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); 912 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
879 // Jump to the constructor function (rax, rbx, rdx passed on). 913 // Jump to the constructor function (rax, rbx, rdx passed on).
880 __ jmp(rcx); 914 __ jmp(rcx);
881 } else { 915 } else {
882 DCHECK_EQ(construct_type, CallableType::kAny); 916 DCHECK_EQ(construct_type, CallableType::kAny);
883 // Call the constructor (rax, rdx, rdi passed on). 917 // Call the constructor (rax, rdx, rdi passed on).
884 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 918 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
885 } 919 }
920
921 // Throw stack overflow exception.
922 __ bind(&stack_overflow);
923 {
924 __ TailCallRuntime(Runtime::kThrowStackOverflow);
925 __ int3();
926 }
886 } 927 }
887 928
888 // static 929 // static
889 void Builtins::Generate_InterpreterPushArgsAndConstructArray( 930 void Builtins::Generate_InterpreterPushArgsAndConstructArray(
890 MacroAssembler* masm) { 931 MacroAssembler* masm) {
891 // ----------- S t a t e ------------- 932 // ----------- S t a t e -------------
892 // -- rax : the number of arguments (not including the receiver) 933 // -- rax : the number of arguments (not including the receiver)
893 // -- rdx : the target to call checked to be Array function. 934 // -- rdx : the target to call checked to be Array function.
894 // -- rbx : the allocation site feedback 935 // -- rbx : the allocation site feedback
895 // -- rcx : the address of the first argument to be pushed. Subsequent 936 // -- rcx : the address of the first argument to be pushed. Subsequent
896 // arguments should be consecutive above this, in the same order as 937 // arguments should be consecutive above this, in the same order as
897 // they are to be pushed onto the stack. 938 // they are to be pushed onto the stack.
898 // ----------------------------------- 939 // -----------------------------------
899 940 Label stack_overflow;
900 // Pop return address to allow tail-call after pushing arguments.
901 __ PopReturnAddressTo(kScratchRegister);
902 941
903 // Number of values to be pushed. 942 // Number of values to be pushed.
904 __ Move(r8, rax); 943 __ Move(r8, rax);
905 __ addp(r8, Immediate(1)); // Add one for receiver. 944 __ addp(r8, Immediate(1)); // Add one for receiver.
906 945
946 // Add a stack check before pushing arguments.
947 Generate_StackOverflowCheck(masm, r8, rdi, r9, &stack_overflow);
948
949 // Pop return address to allow tail-call after pushing arguments.
950 __ PopReturnAddressTo(kScratchRegister);
951
907 // rcx and rdi will be modified. 952 // rcx and rdi will be modified.
908 Generate_InterpreterPushArgs(masm, r8, rcx, rdi); 953 Generate_InterpreterPushArgs(masm, r8, rcx, rdi, r9);
909 954
910 // Push return address in preparation for the tail-call. 955 // Push return address in preparation for the tail-call.
911 __ PushReturnAddressFrom(kScratchRegister); 956 __ PushReturnAddressFrom(kScratchRegister);
912 957
913 // Array constructor expects constructor in rdi. It is same as rdx here. 958 // Array constructor expects constructor in rdi. It is same as rdx here.
914 __ Move(rdi, rdx); 959 __ Move(rdi, rdx);
915 960
916 ArrayConstructorStub stub(masm->isolate()); 961 ArrayConstructorStub stub(masm->isolate());
917 __ TailCallStub(&stub); 962 __ TailCallStub(&stub);
963
964 // Throw stack overflow exception.
965 __ bind(&stack_overflow);
966 {
967 __ TailCallRuntime(Runtime::kThrowStackOverflow);
968 __ int3();
969 }
918 } 970 }
919 971
920 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { 972 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
921 // Set the return address to the correct point in the interpreter entry 973 // Set the return address to the correct point in the interpreter entry
922 // trampoline. 974 // trampoline.
923 Smi* interpreter_entry_return_pc_offset( 975 Smi* interpreter_entry_return_pc_offset(
924 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); 976 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
925 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); 977 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
926 __ Move(rbx, masm->isolate()->builtins()->InterpreterEntryTrampoline()); 978 __ Move(rbx, masm->isolate()->builtins()->InterpreterEntryTrampoline());
927 __ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value() + 979 __ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value() +
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
2110 { 2162 {
2111 // Drop all arguments including the receiver. 2163 // Drop all arguments including the receiver.
2112 __ PopReturnAddressTo(rcx); 2164 __ PopReturnAddressTo(rcx);
2113 __ SmiToInteger32(r8, r8); 2165 __ SmiToInteger32(r8, r8);
2114 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); 2166 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize));
2115 __ PushReturnAddressFrom(rcx); 2167 __ PushReturnAddressFrom(rcx);
2116 __ Ret(); 2168 __ Ret();
2117 } 2169 }
2118 } 2170 }
2119 2171
2120 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
2121 Label* stack_overflow) {
2122 // ----------- S t a t e -------------
2123 // -- rax : actual number of arguments
2124 // -- rbx : expected number of arguments
2125 // -- rdx : new target (passed through to callee)
2126 // -- rdi : function (passed through to callee)
2127 // -----------------------------------
2128 // Check the stack for overflow. We are not trying to catch
2129 // interruptions (e.g. debug break and preemption) here, so the "real stack
2130 // limit" is checked.
2131 Label okay;
2132 __ LoadRoot(r8, Heap::kRealStackLimitRootIndex);
2133 __ movp(rcx, rsp);
2134 // Make rcx the space we have left. The stack might already be overflowed
2135 // here which will cause rcx to become negative.
2136 __ subp(rcx, r8);
2137 // Make r8 the space we need for the array when it is unrolled onto the
2138 // stack.
2139 __ movp(r8, rbx);
2140 __ shlp(r8, Immediate(kPointerSizeLog2));
2141 // Check if the arguments will overflow the stack.
2142 __ cmpp(rcx, r8);
2143 __ j(less_equal, stack_overflow); // Signed comparison.
2144 }
2145
2146 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 2172 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2147 __ pushq(rbp); 2173 __ pushq(rbp);
2148 __ movp(rbp, rsp); 2174 __ movp(rbp, rsp);
2149 2175
2150 // Store the arguments adaptor context sentinel. 2176 // Store the arguments adaptor context sentinel.
2151 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2177 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2152 2178
2153 // Push the function on the stack. 2179 // Push the function on the stack.
2154 __ Push(rdi); 2180 __ Push(rdi);
2155 2181
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 2276
2251 Label enough, too_few; 2277 Label enough, too_few;
2252 __ cmpp(rax, rbx); 2278 __ cmpp(rax, rbx);
2253 __ j(less, &too_few); 2279 __ j(less, &too_few);
2254 __ cmpp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 2280 __ cmpp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
2255 __ j(equal, &dont_adapt_arguments); 2281 __ j(equal, &dont_adapt_arguments);
2256 2282
2257 { // Enough parameters: Actual >= expected. 2283 { // Enough parameters: Actual >= expected.
2258 __ bind(&enough); 2284 __ bind(&enough);
2259 EnterArgumentsAdaptorFrame(masm); 2285 EnterArgumentsAdaptorFrame(masm);
2260 ArgumentsAdaptorStackCheck(masm, &stack_overflow); 2286 // The registers rcx and r8 will be modified. The register rbx is only read.
2287 Generate_StackOverflowCheck(masm, rbx, rcx, r8, &stack_overflow);
2261 2288
2262 // Copy receiver and all expected arguments. 2289 // Copy receiver and all expected arguments.
2263 const int offset = StandardFrameConstants::kCallerSPOffset; 2290 const int offset = StandardFrameConstants::kCallerSPOffset;
2264 __ leap(rax, Operand(rbp, rax, times_pointer_size, offset)); 2291 __ leap(rax, Operand(rbp, rax, times_pointer_size, offset));
2265 __ Set(r8, -1); // account for receiver 2292 __ Set(r8, -1); // account for receiver
2266 2293
2267 Label copy; 2294 Label copy;
2268 __ bind(&copy); 2295 __ bind(&copy);
2269 __ incp(r8); 2296 __ incp(r8);
2270 __ Push(Operand(rax, 0)); 2297 __ Push(Operand(rax, 0));
2271 __ subp(rax, Immediate(kPointerSize)); 2298 __ subp(rax, Immediate(kPointerSize));
2272 __ cmpp(r8, rbx); 2299 __ cmpp(r8, rbx);
2273 __ j(less, &copy); 2300 __ j(less, &copy);
2274 __ jmp(&invoke); 2301 __ jmp(&invoke);
2275 } 2302 }
2276 2303
2277 { // Too few parameters: Actual < expected. 2304 { // Too few parameters: Actual < expected.
2278 __ bind(&too_few); 2305 __ bind(&too_few);
2279 2306
2280 EnterArgumentsAdaptorFrame(masm); 2307 EnterArgumentsAdaptorFrame(masm);
2281 ArgumentsAdaptorStackCheck(masm, &stack_overflow); 2308 // The registers rcx and r8 will be modified. The register rbx is only read.
2309 Generate_StackOverflowCheck(masm, rbx, rcx, r8, &stack_overflow);
2282 2310
2283 // Copy receiver and all actual arguments. 2311 // Copy receiver and all actual arguments.
2284 const int offset = StandardFrameConstants::kCallerSPOffset; 2312 const int offset = StandardFrameConstants::kCallerSPOffset;
2285 __ leap(rdi, Operand(rbp, rax, times_pointer_size, offset)); 2313 __ leap(rdi, Operand(rbp, rax, times_pointer_size, offset));
2286 __ Set(r8, -1); // account for receiver 2314 __ Set(r8, -1); // account for receiver
2287 2315
2288 Label copy; 2316 Label copy;
2289 __ bind(&copy); 2317 __ bind(&copy);
2290 __ incp(r8); 2318 __ incp(r8);
2291 __ Push(Operand(rdi, 0)); 2319 __ Push(Operand(rdi, 0));
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
3134 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3162 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3135 Generate_OnStackReplacementHelper(masm, true); 3163 Generate_OnStackReplacementHelper(masm, true);
3136 } 3164 }
3137 3165
3138 #undef __ 3166 #undef __
3139 3167
3140 } // namespace internal 3168 } // namespace internal
3141 } // namespace v8 3169 } // namespace v8
3142 3170
3143 #endif // V8_TARGET_ARCH_X64 3171 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698