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..e87819c6fa04c1794769e6661e9c64cf694c4fc9 100644 |
--- a/src/builtins/x64/builtins-x64.cc |
+++ b/src/builtins/x64/builtins-x64.cc |
@@ -782,6 +782,26 @@ 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, |
@@ -792,7 +812,6 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, |
__ 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,14 +834,18 @@ 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); |
@@ -839,6 +862,14 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( |
tail_call_mode), |
RelocInfo::CODE_TARGET); |
} |
+ |
+ // Throw stack overflow exception. |
+ __ bind(&stack_overflow); |
+ { |
+ __ TailCallRuntime(Runtime::kThrowStackOverflow); |
+ // This should be unreachable. |
+ __ int3(); |
+ } |
} |
// static |
@@ -854,6 +885,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); |
@@ -883,6 +918,14 @@ 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); |
+ // This should be unreachable. |
+ __ int3(); |
+ } |
} |
// static |
@@ -896,14 +939,18 @@ 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); |
@@ -915,6 +962,14 @@ void Builtins::Generate_InterpreterPushArgsAndConstructArray( |
ArrayConstructorStub stub(masm->isolate()); |
__ TailCallStub(&stub); |
+ |
+ // Throw stack overflow exception. |
+ __ bind(&stack_overflow); |
+ { |
+ __ TailCallRuntime(Runtime::kThrowStackOverflow); |
+ // This should be unreachable. |
+ __ int3(); |
+ } |
} |
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { |
@@ -2117,32 +2172,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 +2286,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 +2308,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; |