Jit: Make most Jit compile failures non-fatal; just abort offending translation
Issue 2175597 Jit compile failures should abort translation, but not the VM
Added new dvmCompileAbort() to replace uses of dvmAbort() when something goes
wrong during the compliation of a trace. In that case, we'll abort the translation
and set it's head to the interpret-only "translation".
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 28dafe7..0d7895f 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -934,7 +934,7 @@
int delta = target - pc;
if (delta & 0x3) {
LOGE("PC-rel distance is not multiples of 4: %d\n", delta);
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
if ((lir->opCode == kThumb2LdrPcRel12) && (delta > 4091)) {
return true;
@@ -978,7 +978,7 @@
int delta = target - pc;
if (delta > 2046 || delta < -2048) {
LOGE("Unconditional branch distance out of range: %d\n", delta);
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
lir->operands[0] = delta >> 1;
} else if (lir->opCode == kThumbBlx1) {
@@ -1626,7 +1626,7 @@
default:
targetOffset = 0; // make gcc happy
LOGE("Unexpected chaining type: %d", i);
- dvmAbort();
+ dvmAbort(); // dvmAbort OK here - can't safely recover
}
COMPILER_TRACE_CHAINING(
LOGD("Jit Runtime: unchaining 0x%x", (int)pChainCells));
diff --git a/vm/compiler/codegen/arm/CodegenCommon.c b/vm/compiler/codegen/arm/CodegenCommon.c
index 6d2ddcd..8f5c11d 100644
--- a/vm/compiler/codegen/arm/CodegenCommon.c
+++ b/vm/compiler/codegen/arm/CodegenCommon.c
@@ -60,7 +60,8 @@
break;
default:
LOGE("Jit: invalid memref kind - %d", memType);
- dvmAbort();
+ assert(0); // Bail if debug build, set worst-case in the field
+ *maskPtr |= ENCODE_ALL;
}
}
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index a496152..21a52d8 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -612,7 +612,7 @@
}
default:
LOGE("Invalid long arith op");
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
if (!callOut) {
genLong3Addr(cUnit, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
@@ -716,7 +716,7 @@
default:
LOGE("Invalid word arith op: 0x%x(%d)",
mir->dalvikInsn.opCode, mir->dalvikInsn.opCode);
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
if (!callOut) {
rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
@@ -1836,7 +1836,7 @@
default:
cond = 0;
LOGE("Unexpected opcode (%d) for Fmt21t\n", dalvikOpCode);
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
/* This mostly likely will be optimized away in a later phase */
@@ -2234,7 +2234,7 @@
default:
cond = 0;
LOGE("Unexpected opcode (%d) for Fmt22t\n", dalvikOpCode);
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
/* This mostly likely will be optimized away in a later phase */
@@ -3106,7 +3106,7 @@
case INLINE_MATH_SIN:
break; /* Handle with C routine */
default:
- dvmAbort();
+ dvmCompilerAbort(cUnit);
}
dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
dvmCompilerClobberCallRegs(cUnit);
@@ -3723,7 +3723,7 @@
mir->offset,
dalvikOpCode, getOpcodeName(dalvikOpCode),
dalvikFormat);
- dvmAbort();
+ dvmCompilerAbort(cUnit);
break;
}
}
@@ -3804,8 +3804,7 @@
#endif
default:
LOGE("Bad blocktype %d", blockList[blockId]->blockType);
- dvmAbort();
- break;
+ dvmCompilerAbort(cUnit);
}
}
}
@@ -3851,19 +3850,22 @@
break;
case kWorkOrderTrace:
/* Start compilation with maximally allowed trace length */
- res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result);
+ res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result,
+ work->bailPtr);
break;
case kWorkOrderTraceDebug: {
bool oldPrintMe = gDvmJit.printMe;
gDvmJit.printMe = true;
/* Start compilation with maximally allowed trace length */
- res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result);
+ res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result,
+ work->bailPtr);
gDvmJit.printMe = oldPrintMe;;
break;
}
default:
res = false;
- dvmAbort();
+ LOGE("Jit: unknown work order type");
+ assert(0); // Bail if debug build, discard oteherwise
}
return res;
}
@@ -3923,7 +3925,7 @@
if (EncodingMap[i].opCode != i) {
LOGE("Encoding order for %s is wrong: expecting %d, seeing %d",
EncodingMap[i].name, i, EncodingMap[i].opCode);
- dvmAbort();
+ dvmAbort(); // OK to dvmAbort - build error
}
}
diff --git a/vm/compiler/codegen/arm/RallocUtil.c b/vm/compiler/codegen/arm/RallocUtil.c
index 131df2c..6d83e73 100644
--- a/vm/compiler/codegen/arm/RallocUtil.c
+++ b/vm/compiler/codegen/arm/RallocUtil.c
@@ -123,7 +123,7 @@
}
}
LOGE("Tried to get info on a non-existant temp: r%d",reg);
- dvmAbort(); // FIXME: abort translation intead of vm
+ dvmCompilerAbort(cUnit);
return NULL;
}
@@ -249,7 +249,7 @@
}
if (required) {
LOGE("No free temp registers");
- dvmAbort(); // FIXME: abort translation instead of vm
+ dvmCompilerAbort(cUnit);
}
return -1; // No register available
}
@@ -298,7 +298,7 @@
next += 2;
}
LOGE("No free temp registers");
- dvmAbort(); // FIXME: abort translation instead of vm
+ dvmCompilerAbort(cUnit);
return -1;
}
@@ -359,7 +359,7 @@
break;
default:
LOGE("Invalid register type");
- dvmAbort(); //FIXME: abort translation instead of vm
+ dvmCompilerAbort(cUnit);
}
return res;
}
@@ -386,7 +386,7 @@
}
}
LOGE("Tried to free a non-existant temp: r%d",reg);
- dvmAbort(); // FIXME: abort translation instead of vm
+ dvmCompilerAbort(cUnit);
}
/*
@@ -460,7 +460,7 @@
}
}
LOGE("Tried to lock a non-existant temp: r%d",reg);
- dvmAbort(); // FIXME: abort translation instead of vm
+ dvmCompilerAbort(cUnit);
}
static void lockArgRegs(CompilationUnit *cUnit)
diff --git a/vm/compiler/codegen/arm/Thumb/Factory.c b/vm/compiler/codegen/arm/Thumb/Factory.c
index 0a44280..ba64922 100644
--- a/vm/compiler/codegen/arm/Thumb/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb/Factory.c
@@ -124,7 +124,8 @@
opCode = kThumbBUncond;
break;
default:
- dvmAbort(); // FIXME: abort trace instead of VM
+ LOGE("Jit: bad case in opNone");
+ dvmCompilerAbort(cUnit);
}
return newLIR0(cUnit, opCode);
}
@@ -145,7 +146,8 @@
opCode = kThumbPop;
break;
default:
- dvmAbort(); // FIXME: abort trace instead of VM
+ LOGE("Jit: bad case in opCondBranch");
+ dvmCompilerAbort(cUnit);
}
return newLIR1(cUnit, opCode, value);
}
@@ -158,7 +160,8 @@
opCode = kThumbBlxR;
break;
default:
- dvmAbort(); // FIXME: abort trace instead of VM
+ LOGE("Jit: bad case in opReg");
+ dvmCompilerAbort(cUnit);
}
return newLIR1(cUnit, opCode, rDestSrc);
}
@@ -203,7 +206,8 @@
}
break;
default:
- dvmAbort(); // FIXME: abort trace instead of VM
+ LOGE("Jit: bad case in opRegImm");
+ dvmCompilerAbort(cUnit);
break;
}
if (shortForm)
@@ -323,7 +327,8 @@
}
return res;
default:
- dvmAbort(); // FIXME - abort trace instead of VM
+ LOGE("Jit: bad case in opRegRegImm");
+ dvmCompilerAbort(cUnit);
break;
}
if (shortForm)
@@ -420,7 +425,8 @@
opRegRegImm(cUnit, kOpLsr, rDestSrc1, rDestSrc1, 16);
return res;
default:
- dvmAbort(); // FIXME - abort trace instead of VM
+ LOGE("Jit: bad case in opRegReg");
+ dvmCompilerAbort(cUnit);
break;
}
return newLIR2(cUnit, opCode, rDestSrc1, rSrc2);
@@ -465,7 +471,8 @@
opCode = kThumbLdrsbRRR;
break;
default:
- dvmAbort(); // FIXME: abort trace instead of VM
+ LOGE("Jit: bad case in loadBaseIndexed");
+ dvmCompilerAbort(cUnit);
}
res = newLIR3(cUnit, opCode, rDest, rBase, rNewIndex);
#if defined(WITH_SELF_VERIFICATION)
@@ -502,7 +509,8 @@
opCode = kThumbStrbRRR;
break;
default:
- dvmAbort(); // FIXME - abort trace instead of VM
+ LOGE("Jit: bad case in storeBaseIndexed");
+ dvmCompilerAbort(cUnit);
}
res = newLIR3(cUnit, opCode, rSrc, rBase, rNewIndex);
#if defined(WITH_SELF_VERIFICATION)
@@ -619,7 +627,8 @@
opCode = kThumbLdrsbRRR;
break;
default:
- dvmAbort(); // FIXME - abort trace instead of VM
+ LOGE("Jit: bad case in loadBaseIndexedBody");
+ dvmCompilerAbort(cUnit);
}
if (shortForm) {
load = res = newLIR3(cUnit, opCode, rDest, rBase, encodedDisp);
@@ -736,7 +745,8 @@
}
break;
default:
- dvmAbort(); // FIXME - abort trace instead of VM
+ LOGE("Jit: bad case in storeBaseIndexedBody");
+ dvmCompilerAbort(cUnit);
}
if (shortForm) {
store = res = newLIR3(cUnit, opCode, rSrc, rBase, encodedDisp);
diff --git a/vm/compiler/codegen/arm/Thumb2/Factory.c b/vm/compiler/codegen/arm/Thumb2/Factory.c
index c4d2c28..eb36193 100644
--- a/vm/compiler/codegen/arm/Thumb2/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb2/Factory.c
@@ -163,7 +163,7 @@
return res;
}
/* No shortcut - go ahead and use literal pool */
- ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 255);
+ ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0);
if (dataTarget == NULL) {
dataTarget = addWordData(cUnit, value, false);
}
diff --git a/vm/compiler/codegen/arm/Thumb2/Gen.c b/vm/compiler/codegen/arm/Thumb2/Gen.c
index b51cdd4..8a574b3 100644
--- a/vm/compiler/codegen/arm/Thumb2/Gen.c
+++ b/vm/compiler/codegen/arm/Thumb2/Gen.c
@@ -142,8 +142,8 @@
case 0:
break;
default:
- assert(0);
- dvmAbort();
+ LOGE("Jit: bad case in genIT");
+ dvmCompilerAbort(cUnit);
}
mask = (mask3 << 3) | (mask2 << 2) | (mask1 << 1) |
(1 << (3 - strlen(guide)));