summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/arm/MethodCodegenDriver.cc
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2011-09-11 15:25:43 -0700
committer buzbee <buzbee@google.com> 2011-09-11 18:14:46 -0700
commitec5adf351879cb6235faf2c6c068c2553d85a7d2 (patch)
treef3f8e9ab69690e729a523188468d7150ede27bf7 /src/compiler/codegen/arm/MethodCodegenDriver.cc
parent005ab2eb9e9ab4762c00e73c7028de2850bd5108 (diff)
Mark top of managed stack on helper transitions
To assist with unwind from a helper function, store current SP prior to helper call in Thread. NOTE: we may wish to push this into a trampoline to reduce code expansion. NOTE #2: Because any helper function which can throw will be non-leaf, it will spill lr at the saved address - 4 (the word immediately below caller's Method*). To identify the callsite, load the spilled lr, clear the low bit, subtract 2, and use that address in the native <-> dalvik mapping to identify the callsite. Also in this CL are a ralloc fix and some extra SSA logging. Change-Id: Idd442f0c55413a5146c24709b1db1150604f4554
Diffstat (limited to 'src/compiler/codegen/arm/MethodCodegenDriver.cc')
-rw-r--r--src/compiler/codegen/arm/MethodCodegenDriver.cc62
1 files changed, 33 insertions, 29 deletions
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 929bbef9ce..7e09ccc469 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -37,7 +37,7 @@ static void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
loadCurrMethodDirect(cUnit, r1); // arg1 <- Method*
loadConstant(cUnit, r0, mir->dalvikInsn.vC); // arg0 <- type_id
loadValueDirectFixed(cUnit, rlSrc, r2); // arg2 <- count
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -67,7 +67,7 @@ static void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
loadCurrMethodDirect(cUnit, r1); // arg1 <- Method*
loadConstant(cUnit, r0, typeId); // arg0 <- type_id
loadConstant(cUnit, r2, elems); // arg2 <- count
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
/*
* NOTE: the implicit target for OP_FILLED_NEW_ARRAY is the
* return region. Because AllocFromCode placed the new array
@@ -154,7 +154,7 @@ static void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
loadValueDirect(cUnit, rlSrc, r2);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
} else {
// fast path
@@ -181,7 +181,7 @@ static void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -212,7 +212,7 @@ static void genSputWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
loadValueDirectWideFixed(cUnit, rlSrc, r2, r3);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
} else {
// fast path
@@ -239,7 +239,7 @@ static void genSputWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -269,7 +269,7 @@ static void genSgetWide(CompilationUnit* cUnit, MIR* mir,
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pGet64Static), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
RegLocation rlResult = oatGetReturnWide(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
} else {
@@ -297,7 +297,7 @@ static void genSgetWide(CompilationUnit* cUnit, MIR* mir,
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -332,7 +332,7 @@ static void genSget(CompilationUnit* cUnit, MIR* mir,
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
} else {
@@ -360,7 +360,7 @@ static void genSget(CompilationUnit* cUnit, MIR* mir,
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -491,7 +491,7 @@ static int nextVCallInsnSP(CompilationUnit* cUnit, MIR* mir,
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
loadConstant(cUnit, r1, dInsn->vB);
- newLIR1(cUnit, kThumbBlxR, rLR);
+ callUnwindableHelper(cUnit, rLR);
genUnconditionalBranch(cUnit, rollback);
// Resume normal slow path
skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -658,7 +658,7 @@ static int nextSuperCallInsnSP(CompilationUnit* cUnit, MIR* mir,
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
loadConstant(cUnit, r1, dInsn->vB);
- newLIR1(cUnit, kThumbBlxR, rLR);
+ callUnwindableHelper(cUnit, rLR);
genUnconditionalBranch(cUnit, rollback);
// Resume normal slow path
skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -686,7 +686,8 @@ static int nextSuperCallInsnSP(CompilationUnit* cUnit, MIR* mir,
tReg = oatAllocTemp(cUnit);
loadWordDisp(cUnit, r0, art::Array::LengthOffset().Int32Value(),
tReg);
- genBoundsCheck(cUnit, tReg, rLR, mir, kArmThrowNoSuchMethod);
+ genRegRegCheck(cUnit, kArmCondCs, tReg, rLR, mir,
+ kArmThrowNoSuchMethod);
oatFreeTemp(cUnit, tReg);
}
// Adjust vtable_ base past object header
@@ -731,7 +732,10 @@ static int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
*/
for (unsigned int i=3; i < dInsn->vA; i++) {
int reg;
- rlArg = oatUpdateLoc(cUnit, oatGetSrc(cUnit, mir, i));
+ // Treating args as untyped 32-bit chunks
+ rlArg = oatGetRawSrc(cUnit, mir, i);
+ rlArg.wide = false;
+ rlArg = oatUpdateLoc(cUnit, rlArg);
if (rlArg.location == kLocPhysReg) {
reg = rlArg.lowReg;
} else {
@@ -838,7 +842,7 @@ static int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
opRegRegImm(cUnit, kOpAdd, r1, rSP, outsOffset);
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pMemcpy), rLR);
loadConstant(cUnit, r2, (numArgs - 3) * 4);
- newLIR1(cUnit, kThumbBlxR, rLR);
+ callNoUnwindHelper(cUnit, rLR);
} else {
// Use vldm/vstm pair using r3 as a temp
int regsLeft = std::min(numArgs - 3, 16);
@@ -908,7 +912,7 @@ static void genInvokeStaticDirect(CompilationUnit* cUnit, MIR* mir,
#ifdef DISPLAY_MISSING_TARGETS
genShowTarget(cUnit);
#endif
- newLIR1(cUnit, kThumbBlxR, rLR);
+ opReg(cUnit, kOpBlx, rLR);
}
/*
@@ -939,7 +943,7 @@ static void genInvokeInterface(CompilationUnit* cUnit, MIR* mir)
#ifdef DISPLAY_MISSING_TARGETS
genShowTarget(cUnit);
#endif
- newLIR1(cUnit, kThumbBlxR, rLR);
+ opReg(cUnit, kOpBlx, rLR);
}
static void genInvokeSuper(CompilationUnit* cUnit, MIR* mir)
@@ -991,7 +995,7 @@ static void genInvokeSuper(CompilationUnit* cUnit, MIR* mir)
#ifdef DISPLAY_MISSING_TARGETS
genShowTarget(cUnit);
#endif
- newLIR1(cUnit, kThumbBlxR, rLR);
+ opReg(cUnit, kOpBlx, rLR);
}
static void genInvokeVirtual(CompilationUnit* cUnit, MIR* mir)
@@ -1030,7 +1034,7 @@ static void genInvokeVirtual(CompilationUnit* cUnit, MIR* mir)
#ifdef DISPLAY_MISSING_TARGETS
genShowTarget(cUnit);
#endif
- newLIR1(cUnit, kThumbBlxR, rLR);
+ opReg(cUnit, kOpBlx, rLR);
}
static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
@@ -1218,7 +1222,7 @@ static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vA);
loadConstant(cUnit, r1, mir->dalvikInsn.vB);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
break;
case OP_ARRAY_LENGTH:
@@ -1839,14 +1843,8 @@ static bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
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 */
+ genRegRegCheck(cUnit, kArmCondCc, rLR, r12, NULL,
+ kArmThrowStackOverflow);
genRegCopy(cUnit, rSP, rLR); // Establish stack
} else {
opRegImm(cUnit, kOpSub, rSP,
@@ -2054,11 +2052,17 @@ static void handleThrowLaunchpads(CompilationUnit *cUnit)
funcOffset =
OFFSETOF_MEMBER(Thread, pThrowNoSuchMethodFromCode);
break;
+ case kArmThrowStackOverflow:
+ funcOffset =
+ OFFSETOF_MEMBER(Thread, pStackOverflowFromCode);
+ // Restore stack alignment
+ opRegImm(cUnit, kOpAdd, rSP, cUnit->numSpills * 4);
+ break;
default:
LOG(FATAL) << "Unexpected throw kind: " << lab->operands[0];
}
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
}
}