diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 5c8b777005..ff8711a613 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -176,7 +176,8 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { } #endif - // Allocate space for locals and initialize them. + // Allocate space for locals and initialize them. This also checks + // for stack overflow. frame_->AllocateStackSlots(); // Initialize the function return target after the locals are set // up, because it needs the expected frame height from the frame. @@ -278,7 +279,6 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { frame_->CallRuntime(Runtime::kTraceEnter, 0); // Ignore the return value. } - CheckStack(); // Compile the body of the function in a vanilla state. Don't // bother compiling all the code if the scope has an illegal @@ -1111,9 +1111,18 @@ void CodeGenerator::CheckStack() { if (FLAG_check_stack) { Comment cmnt(masm_, "[ check stack"); __ LoadRoot(ip, Heap::kStackLimitRootIndex); - __ cmp(sp, Operand(ip)); + // Put the lr setup instruction in the delay slot. The 'sizeof(Instr)' is + // added to the implicit 8 byte offset that always applies to operations + // with pc and gives a return address 12 bytes down. + masm_->add(lr, pc, Operand(sizeof(Instr))); + masm_->cmp(sp, Operand(ip)); StackCheckStub stub; - __ CallStub(&stub, lo); // Call the stub if lower. + // Call the stub if lower. + masm_->mov(pc, + Operand(reinterpret_cast(stub.GetCode().location()), + RelocInfo::CODE_TARGET), + LeaveCC, + lo); } } diff --git a/src/arm/virtual-frame-arm.cc b/src/arm/virtual-frame-arm.cc index 97958606e7..5b5c870ae7 100644 --- a/src/arm/virtual-frame-arm.cc +++ b/src/arm/virtual-frame-arm.cc @@ -141,9 +141,26 @@ void VirtualFrame::AllocateStackSlots() { Adjust(count); // Initialize stack slots with 'undefined' value. __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - for (int i = 0; i < count; i++) { - __ push(ip); - } + } + if (FLAG_check_stack) { + __ LoadRoot(r2, Heap::kStackLimitRootIndex); + } + for (int i = 0; i < count; i++) { + __ push(ip); + } + if (FLAG_check_stack) { + // Put the lr setup instruction in the delay slot. The 'sizeof(Instr)' is + // added to the implicit 8 byte offset that always applies to operations + // with pc and gives a return address 12 bytes down. + masm()->add(lr, pc, Operand(sizeof(Instr))); + masm()->cmp(sp, Operand(r2)); + StackCheckStub stub; + // Call the stub if lower. + masm()->mov(pc, + Operand(reinterpret_cast(stub.GetCode().location()), + RelocInfo::CODE_TARGET), + LeaveCC, + lo); } }