Chromium Code Reviews| Index: src/builtins/x64/builtins-x64.cc |
| diff --git a/src/builtins/x64/builtins-x64.cc b/src/builtins/x64/builtins-x64.cc |
| index 82922239e1f3002ae6e3feddd216a38b9f6ebc73..66a556605ed29539f227fac8e5f257d9b52a1e40 100644 |
| --- a/src/builtins/x64/builtins-x64.cc |
| +++ b/src/builtins/x64/builtins-x64.cc |
| @@ -782,17 +782,36 @@ void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) { |
| __ ret(0); |
| } |
| +static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, |
| + Register scratch1, Register scratch2, |
| + Label* stack_overflow) { |
| + // Check the stack for overflow. We are not trying to catch |
| + // interruptions (e.g. debug break and preemption) here, so the "real stack |
| + // limit" is checked. |
| + __ LoadRoot(scratch1, Heap::kRealStackLimitRootIndex); |
| + __ movp(scratch2, rsp); |
| + // Make scratch2 the space we have left. The stack might already be overflowed |
| + // here which will cause scratch2 to become negative. |
| + __ subp(scratch2, scratch1); |
| + // Make scratch1 the space we need for the array when it is unrolled onto the |
| + // stack. |
| + __ movp(scratch1, num_args); |
| + __ shlp(scratch1, Immediate(kPointerSizeLog2)); |
| + // Check if the arguments will overflow the stack. |
| + __ cmpp(scratch2, scratch1); |
| + __ j(less_equal, stack_overflow); // Signed comparison. |
| +} |
| + |
| static void Generate_InterpreterPushArgs(MacroAssembler* masm, |
| Register num_args, |
| Register start_address, |
| - Register scratch) { |
| + 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.
|
| // Find the address of the last argument. |
| __ Move(scratch, num_args); |
| __ shlp(scratch, Immediate(kPointerSizeLog2)); |
| __ negp(scratch); |
| __ addp(scratch, start_address); |
| - // TODO(mythria): Add a stack check before pushing arguments. |
| // Push the arguments. |
| Label loop_header, loop_check; |
| __ j(always, &loop_check); |
| @@ -815,16 +834,20 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( |
| // they are to be pushed onto the stack. |
| // -- rdi : the target to call (can be any Object). |
| // ----------------------------------- |
| - |
| - // Pop return address to allow tail-call after pushing arguments. |
| - __ PopReturnAddressTo(kScratchRegister); |
| + Label stack_overflow; |
| // Number of values to be pushed. |
| __ Move(rcx, rax); |
| __ addp(rcx, Immediate(1)); // Add one for receiver. |
| + // Add a stack check before pushing arguments. |
| + Generate_StackOverflowCheck(masm, rcx, rdx, r8, &stack_overflow); |
| + |
| + // Pop return address to allow tail-call after pushing arguments. |
| + __ PopReturnAddressTo(kScratchRegister); |
| + |
| // rbx and rdx will be modified. |
| - Generate_InterpreterPushArgs(masm, rcx, rbx, rdx); |
| + Generate_InterpreterPushArgs(masm, rcx, rbx, rdx, r8); |
| // Call the target. |
| __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. |
| @@ -839,6 +862,13 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( |
| tail_call_mode), |
| RelocInfo::CODE_TARGET); |
| } |
| + |
| + // Throw stack overflow exception. |
| + __ bind(&stack_overflow); |
| + { |
| + __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| + __ int3(); |
| + } |
| } |
| // static |
| @@ -854,6 +884,10 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl( |
| // arguments should be consecutive above this, in the same order as |
| // they are to be pushed onto the stack. |
| // ----------------------------------- |
| + Label stack_overflow; |
| + |
| + // Add a stack check before pushing arguments. |
| + Generate_StackOverflowCheck(masm, rax, r8, r9, &stack_overflow); |
| // Pop return address to allow tail-call after pushing arguments. |
| __ PopReturnAddressTo(kScratchRegister); |
| @@ -862,7 +896,7 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl( |
| __ Push(Immediate(0)); |
| // rcx and r8 will be modified. |
| - Generate_InterpreterPushArgs(masm, rax, rcx, r8); |
| + Generate_InterpreterPushArgs(masm, rax, rcx, r8, r9); |
| // Push return address in preparation for the tail-call. |
| __ PushReturnAddressFrom(kScratchRegister); |
| @@ -883,6 +917,13 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl( |
| // Call the constructor (rax, rdx, rdi passed on). |
| __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| } |
| + |
| + // Throw stack overflow exception. |
| + __ bind(&stack_overflow); |
| + { |
| + __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| + __ int3(); |
| + } |
| } |
| // static |
| @@ -896,16 +937,20 @@ void Builtins::Generate_InterpreterPushArgsAndConstructArray( |
| // arguments should be consecutive above this, in the same order as |
| // they are to be pushed onto the stack. |
| // ----------------------------------- |
| - |
| - // Pop return address to allow tail-call after pushing arguments. |
| - __ PopReturnAddressTo(kScratchRegister); |
| + Label stack_overflow; |
| // Number of values to be pushed. |
| __ Move(r8, rax); |
| __ addp(r8, Immediate(1)); // Add one for receiver. |
| + // Add a stack check before pushing arguments. |
| + Generate_StackOverflowCheck(masm, r8, rdi, r9, &stack_overflow); |
| + |
| + // Pop return address to allow tail-call after pushing arguments. |
| + __ PopReturnAddressTo(kScratchRegister); |
| + |
| // rcx and rdi will be modified. |
| - Generate_InterpreterPushArgs(masm, r8, rcx, rdi); |
| + Generate_InterpreterPushArgs(masm, r8, rcx, rdi, r9); |
| // Push return address in preparation for the tail-call. |
| __ PushReturnAddressFrom(kScratchRegister); |
| @@ -915,6 +960,13 @@ void Builtins::Generate_InterpreterPushArgsAndConstructArray( |
| ArrayConstructorStub stub(masm->isolate()); |
| __ TailCallStub(&stub); |
| + |
| + // Throw stack overflow exception. |
| + __ bind(&stack_overflow); |
| + { |
| + __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| + __ int3(); |
| + } |
| } |
| void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { |
| @@ -2117,32 +2169,6 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
| } |
| } |
| -static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
| - Label* stack_overflow) { |
| - // ----------- S t a t e ------------- |
| - // -- rax : actual number of arguments |
| - // -- rbx : expected number of arguments |
| - // -- rdx : new target (passed through to callee) |
| - // -- rdi : function (passed through to callee) |
| - // ----------------------------------- |
| - // Check the stack for overflow. We are not trying to catch |
| - // interruptions (e.g. debug break and preemption) here, so the "real stack |
| - // limit" is checked. |
| - Label okay; |
| - __ LoadRoot(r8, Heap::kRealStackLimitRootIndex); |
| - __ movp(rcx, rsp); |
| - // Make rcx the space we have left. The stack might already be overflowed |
| - // here which will cause rcx to become negative. |
| - __ subp(rcx, r8); |
| - // Make r8 the space we need for the array when it is unrolled onto the |
| - // stack. |
| - __ movp(r8, rbx); |
| - __ shlp(r8, Immediate(kPointerSizeLog2)); |
| - // Check if the arguments will overflow the stack. |
| - __ cmpp(rcx, r8); |
| - __ j(less_equal, stack_overflow); // Signed comparison. |
| -} |
| - |
| static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
| __ pushq(rbp); |
| __ movp(rbp, rsp); |
| @@ -2257,7 +2283,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
| { // Enough parameters: Actual >= expected. |
| __ bind(&enough); |
| EnterArgumentsAdaptorFrame(masm); |
| - ArgumentsAdaptorStackCheck(masm, &stack_overflow); |
| + // The registers rcx and r8 will be modified. The register rbx is only read. |
| + Generate_StackOverflowCheck(masm, rbx, rcx, r8, &stack_overflow); |
| // Copy receiver and all expected arguments. |
| const int offset = StandardFrameConstants::kCallerSPOffset; |
| @@ -2278,7 +2305,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
| __ bind(&too_few); |
| EnterArgumentsAdaptorFrame(masm); |
| - ArgumentsAdaptorStackCheck(masm, &stack_overflow); |
| + // The registers rcx and r8 will be modified. The register rbx is only read. |
| + Generate_StackOverflowCheck(masm, rbx, rcx, r8, &stack_overflow); |
| // Copy receiver and all actual arguments. |
| const int offset = StandardFrameConstants::kCallerSPOffset; |