aboutsummaryrefslogtreecommitdiff
path: root/vm/compiler/codegen/arm/CodegenDriver.c
diff options
context:
space:
mode:
authorBill Buzbee <buzbee@google.com>2010-03-12 16:26:19 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2010-03-12 16:26:19 -0800
commit559dd4cd88ad3da913485f63ccd42344bd0d2544 (patch)
treebaaf8981dfaffbcf82767780b7a50d04610308e0 /vm/compiler/codegen/arm/CodegenDriver.c
parent9bbc7fb5ef119b9f6ab71fdbe375b97ade515b6e (diff)
parentbe6534f384529e51dfba5c3f1b7eb90c86b66e77 (diff)
am be6534f3: Jit: Fix for [Issue 2487514] Dropped exception
Merge commit 'be6534f384529e51dfba5c3f1b7eb90c86b66e77' into dalvik-dev * commit 'be6534f384529e51dfba5c3f1b7eb90c86b66e77': Jit: Fix for [Issue 2487514] Dropped exception
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenDriver.c')
-rw-r--r--vm/compiler/codegen/arm/CodegenDriver.c99
1 files changed, 88 insertions, 11 deletions
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 4e740bef2..8104ef236 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -241,6 +241,16 @@ static void selfVerificationBranchInsertPass(CompilationUnit *cUnit)
}
#endif
+/* Generate conditional branch instructions */
+static ArmLIR *genConditionalBranch(CompilationUnit *cUnit,
+ ArmConditionCode cond,
+ ArmLIR *target)
+{
+ ArmLIR *branch = opCondBranch(cUnit, cond);
+ branch->generic.target = (LIR *) target;
+ return branch;
+}
+
/* Generate a unconditional branch to go to the interpreter */
static inline ArmLIR *genTrap(CompilationUnit *cUnit, int dOffset,
ArmLIR *pcrLabel)
@@ -500,6 +510,81 @@ static void genArrayPut(CompilationUnit *cUnit, MIR *mir, OpSize size,
}
}
+/*
+ * Generate array object store
+ * Must use explicit register allocation here because of
+ * call-out to dvmCanPutArrayElement
+ */
+static void genArrayObjectPut(CompilationUnit *cUnit, MIR *mir,
+ RegLocation rlArray, RegLocation rlIndex,
+ RegLocation rlSrc, int scale)
+{
+ int lenOffset = offsetof(ArrayObject, length);
+ int dataOffset = offsetof(ArrayObject, contents);
+
+ dvmCompilerFlushAllRegs(cUnit);
+
+ int regLen = r0;
+ int regPtr = r4PC; /* Preserved across call */
+ int regArray = r1;
+ int regIndex = r7; /* Preserved across call */
+
+ loadValueDirectFixed(cUnit, rlArray, regArray);
+ loadValueDirectFixed(cUnit, rlIndex, regIndex);
+
+ /* null object? */
+ ArmLIR * pcrLabel = NULL;
+
+ if (!(mir->OptimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+ pcrLabel = genNullCheck(cUnit, rlArray.sRegLow, regArray,
+ mir->offset, NULL);
+ }
+
+ if (!(mir->OptimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+ /* Get len */
+ loadWordDisp(cUnit, regArray, lenOffset, regLen);
+ /* regPtr -> array data */
+ opRegRegImm(cUnit, kOpAdd, regPtr, regArray, dataOffset);
+ genBoundsCheck(cUnit, regIndex, regLen, mir->offset,
+ pcrLabel);
+ } else {
+ /* regPtr -> array data */
+ opRegRegImm(cUnit, kOpAdd, regPtr, regArray, dataOffset);
+ }
+
+ /* Get object to store */
+ loadValueDirectFixed(cUnit, rlSrc, r0);
+ loadConstant(cUnit, r2, (int)dvmCanPutArrayElement);
+
+ /* Are we storing null? If so, avoid check */
+ opRegImm(cUnit, kOpCmp, r0, 0);
+ ArmLIR *branchOver = opCondBranch(cUnit, kArmCondEq);
+
+ /* Make sure the types are compatible */
+ loadWordDisp(cUnit, regArray, offsetof(Object, clazz), r1);
+ loadWordDisp(cUnit, r0, offsetof(Object, clazz), r0);
+ opReg(cUnit, kOpBlx, r2);
+ dvmCompilerClobberCallRegs(cUnit);
+ /* Bad? - roll back and re-execute if so */
+ genRegImmCheck(cUnit, kArmCondEq, r0, 0, mir->offset, pcrLabel);
+
+ /* Resume here - must reload element, regPtr & index preserved */
+ loadValueDirectFixed(cUnit, rlSrc, r0);
+
+ ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
+ target->defMask = ENCODE_ALL;
+ branchOver->generic.target = (LIR *) target;
+
+#if defined(WITH_SELF_VERIFICATION)
+ cUnit->heapMemOp = true;
+#endif
+ storeBaseIndexed(cUnit, regPtr, regIndex, r0,
+ scale, kWord);
+#if defined(WITH_SELF_VERIFICATION)
+ cUnit->heapMemOp = false;
+#endif
+}
+
static bool genShiftOpLong(CompilationUnit *cUnit, MIR *mir,
RegLocation rlDest, RegLocation rlSrc1,
RegLocation rlShift)
@@ -818,16 +903,6 @@ static bool genArithOp(CompilationUnit *cUnit, MIR *mir)
return true;
}
-/* Generate conditional branch instructions */
-static ArmLIR *genConditionalBranch(CompilationUnit *cUnit,
- ArmConditionCode cond,
- ArmLIR *target)
-{
- ArmLIR *branch = opCondBranch(cUnit, cond);
- branch->generic.target = (LIR *) target;
- return branch;
-}
-
/* Generate unconditional branch instructions */
static ArmLIR *genUnconditionalBranch(CompilationUnit *cUnit, ArmLIR *target)
{
@@ -2345,9 +2420,11 @@ static bool handleFmt23x(CompilationUnit *cUnit, MIR *mir)
genArrayPut(cUnit, mir, kLong, rlSrc1, rlSrc2, rlDest, 3);
break;
case OP_APUT:
- case OP_APUT_OBJECT:
genArrayPut(cUnit, mir, kWord, rlSrc1, rlSrc2, rlDest, 2);
break;
+ case OP_APUT_OBJECT:
+ genArrayObjectPut(cUnit, mir, rlSrc1, rlSrc2, rlDest, 2);
+ break;
case OP_APUT_SHORT:
case OP_APUT_CHAR:
genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc1, rlSrc2, rlDest, 1);