Index: src/x64/builtins-x64.cc |
=================================================================== |
--- src/x64/builtins-x64.cc (revision 3200) |
+++ src/x64/builtins-x64.cc (working copy) |
@@ -320,42 +320,23 @@ |
__ push(Operand(rbp, kArgumentsOffset)); |
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
- // Check the stack for overflow or a break request. |
- // We need to catch preemptions right here, otherwise an unlucky preemption |
- // could show up as a failed apply. |
- Label retry_preemption; |
- Label no_preemption; |
- __ bind(&retry_preemption); |
- ExternalReference stack_guard_limit = |
- ExternalReference::address_of_stack_guard_limit(); |
- __ movq(kScratchRegister, stack_guard_limit); |
- __ movq(rcx, rsp); |
- __ subq(rcx, Operand(kScratchRegister, 0)); |
- // rcx contains the difference between the stack limit and the stack top. |
- // We use it below to check that there is enough room for the arguments. |
- __ j(above, &no_preemption); |
- |
- // Preemption! |
- // Because runtime functions always remove the receiver from the stack, we |
- // have to fake one to avoid underflowing the stack. |
- __ push(rax); |
- __ Push(Smi::FromInt(0)); |
- |
- // Do call to runtime routine. |
- __ CallRuntime(Runtime::kStackGuard, 1); |
- __ pop(rax); |
- __ jmp(&retry_preemption); |
- |
- __ bind(&no_preemption); |
- |
+ // Check the stack for overflow. We are not trying need to catch |
+ // interruptions (e.g. debug break and preemption) here, so the "real stack |
+ // limit" is checked. |
Label okay; |
+ __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); |
+ __ movq(rcx, rsp); |
+ // Make rcx the space we have left. The stack might already be overflowed |
+ // here which will cause rcx to become negative. |
+ __ subq(rcx, kScratchRegister); |
// Make rdx the space we need for the array when it is unrolled onto the |
// stack. |
__ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2); |
+ // Check if the arguments will overflow the stack. |
__ cmpq(rcx, rdx); |
- __ j(greater, &okay); |
+ __ j(greater, &okay); // Signed comparison. |
- // Too bad: Out of stack space. |
+ // Out of stack space. |
__ push(Operand(rbp, kFunctionOffset)); |
__ push(rax); |
__ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION); |