Chromium Code Reviews| Index: src/builtins-ia32.cc |
| =================================================================== |
| --- src/builtins-ia32.cc (revision 321) |
| +++ src/builtins-ia32.cc (working copy) |
| @@ -515,16 +515,42 @@ |
| __ push(Operand(ebp, 2 * kPointerSize)); // push arguments |
| __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
| + // We need to catch preemptions right here, otherwise an unlucky preemption |
| + // could show up as a failed apply. |
| + ExternalReference stack_guard_limit = |
| + ExternalReference::address_of_stack_guard_limit(); |
| + Label retry_preemption; |
| + Label no_preemption; |
| + __ bind(&retry_preemption); |
| + __ mov(edi, Operand::StaticVariable(stack_guard_limit)); |
| + __ cmp(esp, Operand(edi)); |
| + __ j(above, &no_preemption, taken); |
|
Søren Thygesen Gjesse
2008/09/26 10:55:19
void Ia32CodeGenerator::CheckStack() uses above_eq
|
| + |
| + // Preemption! |
| + // Because builtins always remove the receiver from the stack, we |
| + // have to fake one to avoid underflowing the stack. |
| + __ push(eax); |
| + __ push(Immediate(Smi::FromInt(0))); |
| + |
| + // Do call to runtime routine. |
| + __ CallRuntime(Runtime::kStackGuard, 1); |
| + __ pop(eax); |
| + __ jmp(&retry_preemption); |
| + |
| + __ bind(&no_preemption); |
| + |
| + // Keep the stack limit in the edi register from here on. |
| // Eagerly check for stack-overflow before pushing all the arguments |
| // to the stack. |
| Label okay; |
| - __ lea(ecx, Operand(esp, -3 * kPointerSize)); // receiver, limit, index |
| + // Make ecx the space we have left. |
| + __ mov(ecx, Operand(esp)); |
| + __ sub(ecx, Operand(edi)); |
| + // Make edx the space we need for the array when it is unrolled onto the |
| + // stack. |
| __ mov(edx, Operand(eax)); |
| __ shl(edx, kPointerSizeLog2 - kSmiTagSize); |
| - __ sub(ecx, Operand(edx)); |
| - ExternalReference stack_guard_limit_address = |
| - ExternalReference::address_of_stack_guard_limit(); |
| - __ cmp(ecx, Operand::StaticVariable(stack_guard_limit_address)); |
| + __ cmp(ecx, Operand(edx)); |
| __ j(greater, &okay, taken); |
| // Too bad: Out of stack space. |