Class cast, fill array and interface exception support.
This change uses the deliver exception mechanism to implement support
for a number of runtime exceptions. It also tidies up code in the
compiler and allocates a singular callee save method in the image.
Also adds a fix for JNI internal test where we weren't passing
Thread::Current() and that this value is now being used in generated code.
Change-Id: I57eefd9afe40e92fa3a7e737f1a2ed7e1094b5c1
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 41053a2..58cd53b 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
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -60,7 +60,7 @@
loadCurrMethodDirect(cUnit, r1); // arg1 <- Method*
loadConstant(cUnit, r0, typeId); // arg0 <- type_id
loadConstant(cUnit, r2, elems); // arg2 <- count
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
/*
* NOTE: the implicit target for OP_FILLED_NEW_ARRAY is the
* return region. Because AllocFromCode placed the new array
@@ -181,7 +181,7 @@
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
loadValueDirect(cUnit, rlSrc, r2);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
} else {
// fast path
@@ -202,7 +202,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -234,7 +234,7 @@
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
loadValueDirectWideFixed(cUnit, rlSrc, r2, r3);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
} else {
// fast path
@@ -255,7 +255,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -286,7 +286,7 @@
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pGet64Static), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
RegLocation rlResult = oatGetReturnWide(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
} else {
@@ -308,7 +308,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -344,7 +344,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
loadCurrMethodDirect(cUnit, r1);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
} else {
@@ -366,7 +366,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
loadConstant(cUnit, r0, typeIdx);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
skipTarget->defMask = ENCODE_ALL;
branchOver->generic.target = (LIR*)skipTarget;
@@ -497,7 +497,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
loadConstant(cUnit, r1, dInsn->vB);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
genUnconditionalBranch(cUnit, rollback);
// Resume normal slow path
skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -664,7 +664,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pResolveMethodFromCode), rLR);
loadConstant(cUnit, r1, dInsn->vB);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
genUnconditionalBranch(cUnit, rollback);
// Resume normal slow path
skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -848,7 +848,7 @@
opRegRegImm(cUnit, kOpAdd, r1, rSP, startOffset);
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pMemcpy), rLR);
loadConstant(cUnit, r2, (numArgs - 3) * 4);
- callNoUnwindHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
// Restore Method*
loadCurrMethodDirect(cUnit, r0);
} else {
@@ -1237,7 +1237,7 @@
OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vA);
loadConstant(cUnit, r1, mir->dalvikInsn.vB);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
break;
case OP_ARRAY_LENGTH:
@@ -2092,7 +2092,7 @@
LOG(FATAL) << "Unexpected throw kind: " << lab->operands[0];
}
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
}
}
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 76d8b45..8f83cbb 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -55,19 +55,7 @@
}
#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)
+static ArmLIR* callRuntimeHelper(CompilationUnit* cUnit, int reg)
{
return opReg(cUnit, kOpBlx, reg);
}
@@ -384,7 +372,7 @@
OFFSETOF_MEMBER(Thread, pHandleFillArrayDataFromCode), rLR);
// Materialize a pointer to the fill data image
newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
}
@@ -437,7 +425,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pFindInstanceFieldFromCode), rLR);
loadConstant(cUnit, r0, fieldIdx);
- callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
+ callRuntimeHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
target->defMask = ENCODE_ALL;
#ifndef EXERCISE_SLOWEST_FIELD_PATH
@@ -632,7 +620,7 @@
OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
genRegCopy(cUnit, r1, mReg);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -674,7 +662,7 @@
OFFSETOF_MEMBER(Thread, pAllocObjectFromCode), rLR);
loadCurrMethodDirect(cUnit, r1); // arg1 <= Method*
loadConstant(cUnit, r0, mir->dalvikInsn.vB); // arg0 <- type_id
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -685,7 +673,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pDeliverException), rLR);
loadValueDirectFixed(cUnit, rlSrc, r0); // Get exception object
- callNoUnwindHelper(cUnit, rLR); // art_deliver_exception(exception);
+ callRuntimeHelper(cUnit, rLR); // art_deliver_exception(exception);
}
static void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
@@ -709,7 +697,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vC);
- callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
+ callRuntimeHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
genRegCopy(cUnit, r2, r0); // Align usage with fast path
// Rejoin code paths
ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -731,7 +719,7 @@
ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq);
genRegCopy(cUnit, r0, r3);
genRegCopy(cUnit, r1, r2);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
/* branch target here */
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -762,7 +750,7 @@
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
loadConstant(cUnit, r0, mir->dalvikInsn.vB);
- callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
+ callRuntimeHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
genRegCopy(cUnit, r2, r0); // Align usage with fast path
// Rejoin code paths
ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -783,7 +771,7 @@
ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); /* If equal, trivial yes */
genRegCopy(cUnit, r0, r1);
genRegCopy(cUnit, r1, r2);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
/* branch target here */
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -948,7 +936,7 @@
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pLockObjectFromCode),
rLR);
genRegCopy(cUnit, r0, rSELF);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
// Resume here
target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -996,7 +984,7 @@
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode),
rLR);
genRegCopy(cUnit, r0, rSELF);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
// Resume here
target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -1084,7 +1072,7 @@
rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
}
- callNoUnwindHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (tgtSize == 1) {
RegLocation rlResult;
@@ -1139,7 +1127,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectFixed(cUnit, rlSrc1, r0);
loadValueDirectFixed(cUnit, rlSrc2, r1);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
rlResult = oatGetReturn(cUnit);
storeValue(cUnit, rlDest, rlResult);
@@ -1185,7 +1173,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
rlResult = oatGetReturnWide(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
@@ -1265,7 +1253,7 @@
OFFSETOF_MEMBER(Thread, pCanPutArrayElementFromCode), rLR);
/* Get the array's clazz */
loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), r1);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
// Now, redo loadValues in case they didn't survive the call
@@ -1455,7 +1443,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
loadValueDirect(cUnit, rlShift, r2);
- callNoUnwindHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
RegLocation rlResult = oatGetReturnWide(cUnit);
storeValueWide(cUnit, rlDest, rlResult);
@@ -1550,7 +1538,7 @@
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (retReg == r0)
rlResult = oatGetReturnWide(cUnit);
@@ -1672,7 +1660,7 @@
if (checkZero) {
genImmedCheck(cUnit, kArmCondEq, r1, 0, mir, kArmThrowDivZero);
}
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (retReg == r0)
rlResult = oatGetReturn(cUnit);
@@ -1732,7 +1720,7 @@
callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self)
#else
ArmLIR* branch = opCondBranch(cUnit, kArmCondEq);
- callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self)
+ callRuntimeHelper(cUnit, rLR); // CheckSuspendFromCode(self)
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
target->defMask = ENCODE_ALL;
branch->generic.target = (LIR*)target;
@@ -1960,7 +1948,7 @@
}
loadWordDisp(cUnit, rSELF, funcOffset, rLR);
loadConstant(cUnit, r1, lit);
- callUnwindableHelper(cUnit, rLR);
+ callRuntimeHelper(cUnit, rLR);
oatClobberCallRegs(cUnit);
if (isDiv)
rlResult = oatGetReturn(cUnit);