diff options
author | Ben Cheng <bccheng@android.com> | 2009-06-08 18:25:27 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@android.com> | 2009-06-09 10:22:02 -0700 |
commit | 1efc9c5e4c5c4c2fccde18e5771c68d064c33bd3 (patch) | |
tree | ce5752fc6cf30cf460483784cdfe4e01eb06bbdf /vm/compiler/codegen/armv5te/Codegen.c | |
parent | 46cd5b63c29d3284a9ff3e0d0711fb136f409313 (diff) | |
download | android_dalvik-1efc9c5e4c5c4c2fccde18e5771c68d064c33bd3.tar.gz android_dalvik-1efc9c5e4c5c4c2fccde18e5771c68d064c33bd3.tar.bz2 android_dalvik-1efc9c5e4c5c4c2fccde18e5771c68d064c33bd3.zip |
Fix two codegen problems: out-of-bound PC-relative addresses and missing branch to the chaining cell at the end of non-branch-ending basic blocks.
Diffstat (limited to 'vm/compiler/codegen/armv5te/Codegen.c')
-rw-r--r-- | vm/compiler/codegen/armv5te/Codegen.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/vm/compiler/codegen/armv5te/Codegen.c b/vm/compiler/codegen/armv5te/Codegen.c index 178e5368b..257272cb4 100644 --- a/vm/compiler/codegen/armv5te/Codegen.c +++ b/vm/compiler/codegen/armv5te/Codegen.c @@ -602,10 +602,11 @@ static void genArrayPut(CompilationUnit *cUnit, MIR *mir, Armv5teOpCode inst, loadValue(cUnit, vArray, r2); loadValue(cUnit, vIndex, r3); - genNullCheck(cUnit, r2, mir->offset, NULL); /* null object? */ + /* null object? */ + Armv5teLIR * pcrLabel = genNullCheck(cUnit, r2, mir->offset, NULL); newLIR3(cUnit, ARMV5TE_LDR_RRI5, r0, r2, lenOffset >> 2); /* Get len */ newLIR2(cUnit, ARMV5TE_ADD_RI8, r2, dataOffset); /* r2 -> array data */ - genBoundsCheck(cUnit, r3, r0, mir->offset, NULL); + genBoundsCheck(cUnit, r3, r0, mir->offset, pcrLabel); /* at this point, r2 points to array, r3 is unscaled index */ if (scale==3) { loadValuePair(cUnit, vSrc, r0, r1); @@ -2491,9 +2492,9 @@ static bool handleFmt51l(CompilationUnit *cUnit, MIR *mir) * Dalvik PC and special-purpose registers are reconstructed here. */ -/* Chaining cell for normal-ending compiles (eg branches) */ -static void handleGenericChainingCell(CompilationUnit *cUnit, - unsigned int offset) +/* Chaining cell for code that may need warmup. */ +static void handleNormalChainingCell(CompilationUnit *cUnit, + unsigned int offset) { newLIR3(cUnit, ARMV5TE_LDR_RRI5, r0, rGLUE, offsetof(InterpState, jitToInterpEntries.dvmJitToInterpNormal) >> 2); @@ -2502,11 +2503,11 @@ static void handleGenericChainingCell(CompilationUnit *cUnit, } /* - * Chaining cell for instructions that immediately following a method - * invocation. + * Chaining cell for instructions that immediately following already translated + * code. */ -static void handlePostInvokeChainingCell(CompilationUnit *cUnit, - unsigned int offset) +static void handleHotChainingCell(CompilationUnit *cUnit, + unsigned int offset) { newLIR3(cUnit, ARMV5TE_LDR_RRI5, r0, rGLUE, offsetof(InterpState, jitToInterpEntries.dvmJitToTraceSelect) >> 2); @@ -2559,6 +2560,12 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) BasicBlock **blockList = cUnit->blockList; + /* + * Reserve space at the beginning of each translation with fillers + * + Chain cell count (2 bytes) + */ + newLIR1(cUnit, ARMV5TE_16BIT_DATA, CHAIN_CELL_OFFSET_TAG); + /* Handle the content in each basic block */ for (i = 0; i < cUnit->numBlocks; i++) { blockList[i]->visited = true; @@ -2578,11 +2585,11 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) labelList[i].opCode = ARMV5TE_PSEUDO_NORMAL_BLOCK_LABEL; } else { switch (blockList[i]->blockType) { - case CHAINING_CELL_GENERIC: - labelList[i].opCode = ARMV5TE_PSEUDO_CHAINING_CELL_GENERIC; + case CHAINING_CELL_NORMAL: + labelList[i].opCode = ARMV5TE_PSEUDO_CHAINING_CELL_NORMAL; /* handle the codegen later */ dvmInsertGrowableList( - &chainingListByType[CHAINING_CELL_GENERIC], (void *) i); + &chainingListByType[CHAINING_CELL_NORMAL], (void *) i); break; case CHAINING_CELL_INVOKE: labelList[i].opCode = ARMV5TE_PSEUDO_CHAINING_CELL_INVOKE; @@ -2592,12 +2599,12 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) dvmInsertGrowableList( &chainingListByType[CHAINING_CELL_INVOKE], (void *) i); break; - case CHAINING_CELL_POST_INVOKE: + case CHAINING_CELL_HOT: labelList[i].opCode = - ARMV5TE_PSEUDO_CHAINING_CELL_POST_INVOKE; + ARMV5TE_PSEUDO_CHAINING_CELL_HOT; /* handle the codegen later */ dvmInsertGrowableList( - &chainingListByType[CHAINING_CELL_POST_INVOKE], + &chainingListByType[CHAINING_CELL_HOT], (void *) i); break; case PC_RECONSTRUCTION: @@ -2732,10 +2739,17 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) dalvikFormat); dvmAbort(); break; - } else { - gDvmJit.opHistogram[dalvikOpCode]++; } } + /* + * Check if the block is terminated due to trace length constraint - + * insert an unconditional branch to the chaining cell. + */ + if (blockList[i]->needFallThroughBranch) { + genUnconditionalBranch(cUnit, + &labelList[blockList[i]->fallThrough->id]); + } + } /* Handle the codegen in predefined order */ @@ -2763,16 +2777,16 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) switch (blockList[blockId]->blockType) { - case CHAINING_CELL_GENERIC: - handleGenericChainingCell(cUnit, + case CHAINING_CELL_NORMAL: + handleNormalChainingCell(cUnit, blockList[blockId]->startOffset); break; case CHAINING_CELL_INVOKE: handleInvokeChainingCell(cUnit, blockList[blockId]->containingMethod); break; - case CHAINING_CELL_POST_INVOKE: - handlePostInvokeChainingCell(cUnit, + case CHAINING_CELL_HOT: + handleHotChainingCell(cUnit, blockList[blockId]->startOffset); break; default: @@ -2797,7 +2811,8 @@ void *dvmCompilerDoWork(CompilerWorkOrder *work) res = dvmCompileMethod(work->info); break; case kWorkOrderTrace: - res = dvmCompileTrace(work->info); + /* Start compilation with maximally allowed trace length */ + res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN); break; default: res = NULL; |