diff options
Diffstat (limited to 'vm/compiler')
-rw-r--r-- | vm/compiler/Compiler.c | 14 | ||||
-rw-r--r-- | vm/compiler/Compiler.h | 5 | ||||
-rw-r--r-- | vm/compiler/CompilerIR.h | 3 | ||||
-rw-r--r-- | vm/compiler/Frontend.c | 11 | ||||
-rw-r--r-- | vm/compiler/IntermediateRep.c | 3 | ||||
-rw-r--r-- | vm/compiler/Loop.c | 6 | ||||
-rw-r--r-- | vm/compiler/Utility.c | 18 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Assemble.c | 6 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/CodegenCommon.c | 3 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 26 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/RallocUtil.c | 12 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Thumb/Factory.c | 30 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Thumb2/Factory.c | 2 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Thumb2/Gen.c | 4 |
14 files changed, 89 insertions, 54 deletions
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c index 13749ac50..597fbb246 100644 --- a/vm/compiler/Compiler.c +++ b/vm/compiler/Compiler.c @@ -479,11 +479,17 @@ static void *compilerThreadStart(void *arg) if (gDvmJit.haltCompilerThread) { LOGD("Compiler shutdown in progress - discarding request"); } else if (!gDvmJit.codeCacheFull) { - /* If compilation failed, use interpret-template */ - if (!dvmCompilerDoWork(&work)) { - work.result.codeAddress = gDvmJit.interpretTemplate; + bool compileOK = false; + jmp_buf jmpBuf; + work.bailPtr = &jmpBuf; + bool aborted = setjmp(jmpBuf); + if (!aborted) { + compileOK = dvmCompilerDoWork(&work); } - if (!work.result.discardResult) { + if (aborted || !compileOK) { + dvmCompilerArenaReset(); + work.result.codeAddress = gDvmJit.interpretTemplate; + } else if (!work.result.discardResult) { dvmJitSetCodeAddr(work.pc, work.result.codeAddress, work.result.instructionSet); } diff --git a/vm/compiler/Compiler.h b/vm/compiler/Compiler.h index de3068697..f264c5b16 100644 --- a/vm/compiler/Compiler.h +++ b/vm/compiler/Compiler.h @@ -15,6 +15,7 @@ */ #include <Thread.h> +#include <setjmp.h> #ifndef _DALVIK_VM_COMPILER #define _DALVIK_VM_COMPILER @@ -56,6 +57,7 @@ typedef struct CompilerWorkOrder { WorkOrderKind kind; void* info; JitTranslationInfo result; + jmp_buf *bailPtr; } CompilerWorkOrder; /* Chain cell for predicted method invocation */ @@ -152,7 +154,7 @@ bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info); void *dvmCheckCodeCache(void *method); bool dvmCompileMethod(const Method *method, JitTranslationInfo *info); bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts, - JitTranslationInfo *info); + JitTranslationInfo *info, jmp_buf *bailPtr); void dvmCompilerDumpStats(void); void dvmCompilerDrainQueue(void); void dvmJitUnchainAll(void); @@ -185,5 +187,4 @@ void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit, void dvmCompilerStateRefresh(void); JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc, const struct JitEntry *desc); - #endif /* _DALVIK_VM_COMPILER */ diff --git a/vm/compiler/CompilerIR.h b/vm/compiler/CompilerIR.h index 00892faaf..00a45f920 100644 --- a/vm/compiler/CompilerIR.h +++ b/vm/compiler/CompilerIR.h @@ -157,6 +157,7 @@ typedef struct CompilationUnit { LIR *chainingCellBottom; struct RegisterPool *regPool; int optRound; // round number to tell an LIR's age + jmp_buf *bailPtr; JitInstructionSetType instructionSet; /* Number of total regs used in the whole cUnit after SSA transformation */ int numSSARegs; @@ -195,6 +196,8 @@ void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR); void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR); +void dvmCompilerAbort(CompilationUnit *cUnit); + /* Debug Utilities */ void dvmCompilerDumpCompilationUnit(CompilationUnit *cUnit); diff --git a/vm/compiler/Frontend.c b/vm/compiler/Frontend.c index 0c8a8df0e..d97001ff5 100644 --- a/vm/compiler/Frontend.c +++ b/vm/compiler/Frontend.c @@ -286,7 +286,7 @@ bool filterMethodByCallGraph(Thread *thread, const char *curMethodName) * bytecode into machine code. */ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts, - JitTranslationInfo *info) + JitTranslationInfo *info, jmp_buf *bailPtr) { const DexCode *dexCode = dvmGetMethodCode(desc->method); const JitTraceRun* currRun = &desc->trace[0]; @@ -316,6 +316,9 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts, methodStats = analyzeMethodBody(desc->method); #endif + /* Set the recover buffer pointer */ + cUnit.bailPtr = bailPtr; + /* Initialize the printMe flag */ cUnit.printMe = gDvmJit.printMe; @@ -760,7 +763,7 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts, /* Halve the instruction count and retry again */ } else { - return dvmCompileTrace(desc, cUnit.numInsts / 2, info); + return dvmCompileTrace(desc, cUnit.numInsts / 2, info, bailPtr); } } @@ -896,7 +899,7 @@ bool dvmCompileMethod(const Method *method, JitTranslationInfo *info) if (numBlocks != cUnit.numBlocks) { LOGE("Expect %d vs %d basic blocks\n", numBlocks, cUnit.numBlocks); - dvmAbort(); + dvmCompilerAbort(&cUnit); } /* Connect the basic blocks through the taken links */ @@ -930,7 +933,7 @@ bool dvmCompileMethod(const Method *method, JitTranslationInfo *info) if (j == numBlocks && !isInvoke) { LOGE("Target not found for insn %x: expect target %x\n", curBB->lastMIRInsn->offset, target); - dvmAbort(); + dvmCompilerAbort(&cUnit); } } } diff --git a/vm/compiler/IntermediateRep.c b/vm/compiler/IntermediateRep.c index 018d8907a..b3e64907b 100644 --- a/vm/compiler/IntermediateRep.c +++ b/vm/compiler/IntermediateRep.c @@ -81,8 +81,7 @@ void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir) */ void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR) { - if (currentLIR->prev == NULL) - dvmAbort(); + assert(currentLIR->prev != NULL); LIR *prevLIR = currentLIR->prev; prevLIR->next = newLIR; diff --git a/vm/compiler/Loop.c b/vm/compiler/Loop.c index e996ca2ee..ef76c508f 100644 --- a/vm/compiler/Loop.c +++ b/vm/compiler/Loop.c @@ -314,7 +314,8 @@ static bool doLoopBodyCodeMotion(CompilationUnit *cUnit) break; default: refIdx = 0; - dvmAbort(); + LOGE("Jit: bad case in doLoopBodyCodeMotion"); + dvmCompilerAbort(cUnit); } int useIdx = refIdx + 1; @@ -449,7 +450,8 @@ static void genHoistedChecks(CompilationUnit *cUnit) dvmCompilerAppendMIR(entry, boundCheckMIR); } } else { - dvmAbort(); + LOGE("Jit: bad case in genHoistedChecks"); + dvmCompilerAbort(cUnit); } } diff --git a/vm/compiler/Utility.c b/vm/compiler/Utility.c index 26bb3d082..83caab745 100644 --- a/vm/compiler/Utility.c +++ b/vm/compiler/Utility.c @@ -66,11 +66,7 @@ retry: * could go above the limit we need to enhance the allocation * mechanism. */ - if (size > ARENA_DEFAULT_SIZE) { - LOGE("Requesting %d bytes which exceed the maximal size allowed\n", - size); - dvmAbort(); - } + assert(size <= ARENA_DEFAULT_SIZE); /* Time to allocate a new arena */ ArenaMemBlock *newArena = (ArenaMemBlock *) malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE); @@ -281,3 +277,15 @@ void dvmDebugBitVector(char *msg, const BitVector *bv, int length) } } } + +void dvmCompilerAbort(CompilationUnit *cUnit) +{ + LOGE("Jit: aborting trace compilation, reverting to interpreter"); + /* Force a traceback in debug builds */ + assert(0); + /* + * Abort translation and force to interpret-only for this trace + * Matching setjmp in compiler thread work loop in Compiler.c. + */ + longjmp(*cUnit->bailPtr, 1); +} diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c index 28dafe710..0d7895f23 100644 --- a/vm/compiler/codegen/arm/Assemble.c +++ b/vm/compiler/codegen/arm/Assemble.c @@ -934,7 +934,7 @@ static bool assembleInstructions(CompilationUnit *cUnit, intptr_t startAddr) 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 @@ static bool assembleInstructions(CompilationUnit *cUnit, intptr_t startAddr) 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 @@ u4* dvmJitUnchain(void* codeAddr) 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 6d2ddcd40..8f5c11da4 100644 --- a/vm/compiler/codegen/arm/CodegenCommon.c +++ b/vm/compiler/codegen/arm/CodegenCommon.c @@ -60,7 +60,8 @@ static void setMemRefType(ArmLIR *lir, bool isLoad, int memType) 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 8502f4882..434dbbfa4 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.c +++ b/vm/compiler/codegen/arm/CodegenDriver.c @@ -612,7 +612,7 @@ static bool genArithOpLong(CompilationUnit *cUnit, MIR *mir, } default: LOGE("Invalid long arith op"); - dvmAbort(); + dvmCompilerAbort(cUnit); } if (!callOut) { genLong3Addr(cUnit, firstOp, secondOp, rlDest, rlSrc1, rlSrc2); @@ -716,7 +716,7 @@ static bool genArithOpInt(CompilationUnit *cUnit, MIR *mir, 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 @@ static bool handleFmt21t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb, 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 @@ static bool handleFmt22t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb, 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 @@ static bool handleExecuteInline(CompilationUnit *cUnit, MIR *mir) 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 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) mir->offset, dalvikOpCode, getOpcodeName(dalvikOpCode), dalvikFormat); - dvmAbort(); + dvmCompilerAbort(cUnit); break; } } @@ -3804,8 +3804,7 @@ gen_fallthrough: #endif default: LOGE("Bad blocktype %d", blockList[blockId]->blockType); - dvmAbort(); - break; + dvmCompilerAbort(cUnit); } } } @@ -3851,19 +3850,22 @@ bool dvmCompilerDoWork(CompilerWorkOrder *work) 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 @@ bool dvmCompilerArchInit() 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 131df2c7b..6d83e73e0 100644 --- a/vm/compiler/codegen/arm/RallocUtil.c +++ b/vm/compiler/codegen/arm/RallocUtil.c @@ -123,7 +123,7 @@ static RegisterInfo *getRegInfo(CompilationUnit *cUnit, int reg) } } 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 @@ static int allocTempBody(CompilationUnit *cUnit, RegisterInfo *p, int numTemps, } 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 @@ extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit) next += 2; } LOGE("No free temp registers"); - dvmAbort(); // FIXME: abort translation instead of vm + dvmCompilerAbort(cUnit); return -1; } @@ -359,7 +359,7 @@ static RegisterInfo *allocLive(CompilationUnit *cUnit, int sReg, break; default: LOGE("Invalid register type"); - dvmAbort(); //FIXME: abort translation instead of vm + dvmCompilerAbort(cUnit); } return res; } @@ -386,7 +386,7 @@ extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg) } } LOGE("Tried to free a non-existant temp: r%d",reg); - dvmAbort(); // FIXME: abort translation instead of vm + dvmCompilerAbort(cUnit); } /* @@ -460,7 +460,7 @@ extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg) } } 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 0a4428043..ba6492293 100644 --- a/vm/compiler/codegen/arm/Thumb/Factory.c +++ b/vm/compiler/codegen/arm/Thumb/Factory.c @@ -124,7 +124,8 @@ static ArmLIR *opNone(CompilationUnit *cUnit, OpKind op) 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 @@ static ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value) 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 @@ static ArmLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc) 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 @@ static ArmLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, } break; default: - dvmAbort(); // FIXME: abort trace instead of VM + LOGE("Jit: bad case in opRegImm"); + dvmCompilerAbort(cUnit); break; } if (shortForm) @@ -323,7 +327,8 @@ static ArmLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest, } 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 @@ static ArmLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1, 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 @@ static ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase, 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 @@ static ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase, 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 @@ static ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase, 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 @@ static ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase, } 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 c4d2c2824..eb361934c 100644 --- a/vm/compiler/codegen/arm/Thumb2/Factory.c +++ b/vm/compiler/codegen/arm/Thumb2/Factory.c @@ -163,7 +163,7 @@ static ArmLIR *loadConstantValue(CompilationUnit *cUnit, int rDest, int value) 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 b51cdd4bb..8a574b3ca 100644 --- a/vm/compiler/codegen/arm/Thumb2/Gen.c +++ b/vm/compiler/codegen/arm/Thumb2/Gen.c @@ -142,8 +142,8 @@ static ArmLIR *genIT(CompilationUnit *cUnit, ArmConditionCode code, 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))); |