From cefd1878e09fb0fb519a175545a99eb8c4a375b2 Mon Sep 17 00:00:00 2001 From: buzbee Date: Fri, 9 Sep 2011 09:59:52 -0700 Subject: Add stack overflow check Change-Id: I67fcb5ad4bda304879ce05561b03aa7cd46e9990 --- src/compiler/codegen/arm/MethodCodegenDriver.cc | 30 ++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'src/compiler/codegen/arm/MethodCodegenDriver.cc') diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc index cf1ad0473e..2319a712e9 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -1809,14 +1809,42 @@ static bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb) oatLockTemp(cUnit, r1); oatLockTemp(cUnit, r2); oatLockTemp(cUnit, r3); + + /* + * We can safely skip the stack overflow check if we're + * a leaf *and* our frame size < fudge factor. + */ + bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) && + ((size_t)cUnit->frameSize < + art::Thread::kStackOverflowReservedBytes)); newLIR0(cUnit, kArmPseudoMethodEntry); + if (!skipOverflowCheck) { + /* Load stack limit */ + loadWordDisp(cUnit, rSELF, + art::Thread::StackEndOffset().Int32Value(), r12); + } /* Spill core callee saves */ newLIR1(cUnit, kThumb2Push, cUnit->coreSpillMask); /* Need to spill any FP regs? */ if (cUnit->numFPSpills) { newLIR1(cUnit, kThumb2VPushCS, cUnit->numFPSpills); } - opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - (cUnit->numSpills * 4)); + if (!skipOverflowCheck) { + opRegRegImm(cUnit, kOpSub, rLR, rSP, + cUnit->frameSize - (cUnit->numSpills * 4)); + opRegReg(cUnit, kOpCmp, rLR, r12); // Stack overflow? + /* Begin conditional skip */ + genIT(cUnit, kArmCondCc, "TT"); // Carry clear; unsigned < + loadWordDisp(cUnit, rSELF, + OFFSETOF_MEMBER(Thread, pStackOverflowFromCode), rLR); + newLIR2(cUnit, kThumbAddRI8, rSP, cUnit->numSpills * 4); + opReg(cUnit, kOpBlx, rLR); + /* End conditional skip */ + genRegCopy(cUnit, rSP, rLR); // Establish stack + } else { + opRegImm(cUnit, kOpSub, rSP, + cUnit->frameSize - (cUnit->numSpills * 4)); + } storeBaseDisp(cUnit, rSP, 0, r0, kWord); flushIns(cUnit); oatFreeTemp(cUnit, r0); -- cgit v1.2.3-59-g8ed1b