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
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index 1fe680f..76cff17 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -833,7 +833,11 @@
{
RegisterInfo* newInfo = getRegInfo(cUnit, newReg);
RegisterInfo* oldInfo = getRegInfo(cUnit, oldReg);
+ // Target temp status must not change
+ bool isTemp = newInfo->isTemp;
*newInfo = *oldInfo;
+ // Restore target's temp status
+ newInfo->isTemp = isTemp;
newInfo->reg = newReg;
}
@@ -1011,7 +1015,12 @@
{
RegLocation res = cUnit->regLocation[mir->ssaRep->defs[num]];
#ifdef SSA_WORKAROUND
- res.wide = false;
+ if (res.wide) {
+ LOG(WARNING) << "Invalid SSA renaming: " << PrettyMethod(cUnit->method);
+ cUnit->printMe = true;
+ cUnit->dumpCFG = true;
+ res.wide = false;
+ }
#endif
assert(!res.wide);
return res;
@@ -1020,7 +1029,12 @@
{
RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]];
#ifdef SSA_WORKAROUND
- res.wide = false;
+ if (res.wide) {
+ LOG(WARNING) << "Invalid SSA renaming: " << PrettyMethod(cUnit->method);
+ cUnit->printMe = true;
+ cUnit->dumpCFG = true;
+ res.wide = false;
+ }
#endif
assert(!res.wide);
return res;
@@ -1035,7 +1049,12 @@
{
RegLocation res = cUnit->regLocation[mir->ssaRep->defs[low]];
#ifdef SSA_WORKAROUND
- res.wide = true;
+ if (!res.wide) {
+ LOG(WARNING) << "Invalid SSA renaming: " << PrettyMethod(cUnit->method);
+ cUnit->printMe = true;
+ cUnit->dumpCFG = true;
+ res.wide = true;
+ }
#endif
assert(res.wide);
return res;
@@ -1046,7 +1065,12 @@
{
RegLocation res = cUnit->regLocation[mir->ssaRep->uses[low]];
#ifdef SSA_WORKAROUND
- res.wide = true;
+ if (!res.wide) {
+ LOG(WARNING) << "Invalid SSA renaming: " << PrettyMethod(cUnit->method);
+ cUnit->printMe = true;
+ cUnit->dumpCFG = true;
+ res.wide = true;
+ }
#endif
assert(res.wide);
return res;
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index 66eaf54..34a333d 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -62,7 +62,7 @@
if (cCode == kArmCondAl) {
branch = genUnconditionalBranch(cUnit, tgt);
} else {
- branch = genCmpImmBranch(cUnit, kArmCondEq, reg, 0);
+ branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
branch->generic.target = (LIR*)tgt;
}
// Remember branch target - will process later
@@ -86,18 +86,18 @@
return genImmedCheck(cUnit, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
}
-/* Perform bound check on two registers */
-static TGT_LIR* genBoundsCheck(CompilationUnit* cUnit, int rIndex,
- int rBound, MIR* mir, ArmThrowKind kind)
+/* Perform check on two registers */
+static TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
+ int reg1, int reg2, MIR* mir, ArmThrowKind kind)
{
ArmLIR* tgt = (ArmLIR*)oatNew(sizeof(ArmLIR), true);
tgt->opcode = kArmPseudoThrowTarget;
tgt->operands[0] = kind;
- tgt->operands[1] = mir->offset;
- tgt->operands[2] = rIndex;
- tgt->operands[3] = rBound;
- opRegReg(cUnit, kOpCmp, rIndex, rBound);
- ArmLIR* branch = genConditionalBranch(cUnit, kArmCondCs, tgt);
+ tgt->operands[1] = mir ? mir->offset : 0;
+ tgt->operands[2] = reg1;
+ tgt->operands[3] = reg2;
+ opRegReg(cUnit, kOpCmp, reg1, reg2);
+ ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
// Remember branch target - will process later
oatInsertGrowableList(&cUnit->throwLaunchpads, (intptr_t)tgt);
return branch;
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index b35f39f..212358f 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -356,6 +356,7 @@
kArmThrowInternalError,
kArmThrowRuntimeException,
kArmThrowNoSuchMethod,
+ kArmThrowStackOverflow,
} ArmThrowKind;
#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 929bbef..7e09ccc 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -37,7 +37,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*/
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 @@
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 @@
#ifdef DISPLAY_MISSING_TARGETS
genShowTarget(cUnit);
#endif
- newLIR1(cUnit, kThumbBlxR, rLR);
+ opReg(cUnit, kOpBlx, rLR);
}
/*
@@ -939,7 +943,7 @@
#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 @@
#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 @@
#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 @@
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 @@
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 @@
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);
}
}
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 1ce7394..db4dd09 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -55,6 +55,23 @@
}
#endif
+/*
+ * If a helper routine might need to unwind, let it know the top
+ * of the managed stack.
+ */
+static ArmLIR* callUnwindableHelper(CompilationUnit* cUnit, int reg)
+{
+ // Starting point for managed traceback if we throw
+ storeWordDisp(cUnit, rSELF,
+ art::Thread::TopOfManagedStackOffset().Int32Value(), rSP);
+ return opReg(cUnit, kOpBlx, reg);
+}
+
+static ArmLIR* callNoUnwindHelper(CompilationUnit* cUnit, int reg)
+{
+ return opReg(cUnit, kOpBlx, reg);
+}
+
/* Generate unconditional branch instructions */
static ArmLIR* genUnconditionalBranch(CompilationUnit* cUnit, ArmLIR* target)
{
@@ -367,7 +384,7 @@
OFFSETOF_MEMBER(Thread, pHandleFillArrayDataFromCode), rLR);
// Materialize a pointer to the fill data image
newLIR3(cUnit, kThumb2AdrST, r1, 0, (intptr_t)tabRec);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
}
@@ -420,7 +437,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pFindFieldFromCode), rLR);
loadConstant(cUnit, r0, fieldIdx);
- opReg(cUnit, kOpBlx, rLR); // resolveTypeFromCode(idx, method)
+ callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
target->defMask = ENCODE_ALL;
#ifndef EXERCISE_SLOWEST_FIELD_PATH
@@ -615,7 +632,7 @@
OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
genRegCopy(cUnit, r1, mReg);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
- opReg(cUnit, kOpBlx, rLR); // resolveTypeFromCode(idx, method)
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -657,7 +674,7 @@
OFFSETOF_MEMBER(Thread, pAllocObjectFromCode), rLR);
loadCurrMethodDirect(cUnit, r1); // arg1 <= Method*
loadConstant(cUnit, r0, mir->dalvikInsn.vB); // arg0 <- type_id
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -669,7 +686,7 @@
OFFSETOF_MEMBER(Thread, pThrowException), rLR);
loadValueDirectFixed(cUnit, rlSrc, r1); // Get exception object
genRegCopy(cUnit, r0, rSELF);
- opReg(cUnit, kOpBlx, rLR); // artThrowException(thread, exception);
+ callUnwindableHelper(cUnit, rLR); // artThrowException(thread, exception);
}
static void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
@@ -693,7 +710,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vC);
- opReg(cUnit, kOpBlx, rLR); // resolveTypeFromCode(idx, method)
+ callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
genRegCopy(cUnit, r2, r0); // Align usage with fast path
// Rejoin code paths
ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -715,7 +732,7 @@
ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq);
genRegCopy(cUnit, r0, r3);
genRegCopy(cUnit, r1, r2);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
/* branch target here */
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -746,7 +763,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
- opReg(cUnit, kOpBlx, rLR); // resolveTypeFromCode(idx, method)
+ callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
genRegCopy(cUnit, r2, r0); // Align usage with fast path
// Rejoin code paths
ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -767,7 +784,7 @@
ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); /* If equal, trivial yes */
genRegCopy(cUnit, r0, r1);
genRegCopy(cUnit, r1, r2);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
/* branch target here */
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -936,7 +953,7 @@
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pLockObjectFromCode),
rLR);
genRegCopy(cUnit, r0, rSELF);
- newLIR1(cUnit, kThumbBlxR, rLR);
+ callUnwindableHelper(cUnit, rLR);
// Resume here
target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -986,7 +1003,7 @@
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode),
rLR);
genRegCopy(cUnit, r0, rSELF);
- newLIR1(cUnit, kThumbBlxR, rLR);
+ callUnwindableHelper(cUnit, rLR);
// Resume here
target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -1074,7 +1091,7 @@
rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
}
- opReg(cUnit, kOpBlx, rLR);
+ callNoUnwindHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (tgtSize == 1) {
RegLocation rlResult;
@@ -1129,7 +1146,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectFixed(cUnit, rlSrc1, r0);
loadValueDirectFixed(cUnit, rlSrc2, r1);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -1175,7 +1192,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
rlResult = oatGetReturnWide(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
@@ -1261,7 +1278,7 @@
loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), r1);
/* Get the object's clazz */
loadWordDisp(cUnit, r0, Object::ClassOffset().Int32Value(), r0);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
// Now, redo loadValues in case they didn't survive the call
@@ -1285,7 +1302,7 @@
loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
/* regPtr -> array data */
opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
- genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir,
+ genRegRegCheck(cUnit, kArmCondCs, rlIndex.lowReg, regLen, mir,
kArmThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
} else {
@@ -1328,7 +1345,7 @@
loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
/* regPtr -> array data */
opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
- genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir,
+ genRegRegCheck(cUnit, kArmCondCs, rlIndex.lowReg, regLen, mir,
kArmThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
} else {
@@ -1401,7 +1418,7 @@
loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
/* regPtr -> array data */
opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
- genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir,
+ genRegRegCheck(cUnit, kArmCondCs, rlIndex.lowReg, regLen, mir,
kArmThrowArrayBounds);
oatFreeTemp(cUnit, regLen);
} else {
@@ -1459,7 +1476,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
loadValueDirect(cUnit, rlShift, r2);
- opReg(cUnit, kOpBlx, rLR);
+ callNoUnwindHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturnWide(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
@@ -1554,7 +1571,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (retReg == r0)
rlResult = oatGetReturnWide(cUnit);
@@ -1676,7 +1693,7 @@
if (checkZero) {
genImmedCheck(cUnit, kArmCondEq, r1, 0, mir, kArmThrowDivZero);
}
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (retReg == r0)
rlResult = oatGetReturn(cUnit);
@@ -1701,7 +1718,7 @@
genRegCopy(cUnit, r0, rSELF);
opRegImm(cUnit, kOpCmp, rSuspendCount, 0);
genIT(cUnit, kArmCondNe, "");
- opReg(cUnit, kOpBlx, rLR); // CheckSuspendFromCode(self)
+ callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self)
oatFreeCallTemps(cUnit);
}
@@ -1925,7 +1942,7 @@
}
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadConstant(cUnit, r1, lit);
- opReg(cUnit, kOpBlx, rLR);
+ callUnwindableHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (isDiv)
rlResult = oatGetReturn(cUnit);