aboutsummaryrefslogtreecommitdiff
path: root/vm/compiler/codegen/arm/CodegenDriver.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenDriver.c')
-rw-r--r--vm/compiler/codegen/arm/CodegenDriver.c188
1 files changed, 83 insertions, 105 deletions
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 02c39f6d0..b265579e9 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -205,7 +205,7 @@ static bool genConversionPortable(CompilationUnit *cUnit, MIR *mir)
static void selfVerificationBranchInsert(LIR *currentLIR, ArmOpcode opcode,
int dest, int src1)
{
- ArmLIR *insn = dvmCompilerNew(sizeof(ArmLIR), true);
+ ArmLIR *insn = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
insn->opcode = opcode;
insn->operands[0] = dest;
insn->operands[1] = src1;
@@ -912,12 +912,12 @@ static void genReturnCommon(CompilationUnit *cUnit, MIR *mir)
/* Insert branch, but defer setting of target */
ArmLIR *branch = genUnconditionalBranch(cUnit, NULL);
/* Set up the place holder to reconstruct this Dalvik PC */
- ArmLIR *pcrLabel = dvmCompilerNew(sizeof(ArmLIR), true);
+ ArmLIR *pcrLabel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
pcrLabel->opcode = kArmPseudoPCReconstructionCell;
pcrLabel->operands[0] = dPC;
pcrLabel->operands[1] = mir->offset;
/* Insert the place holder to the growable list */
- dvmInsertGrowableList(&cUnit->pcReconstructionList, pcrLabel);
+ dvmInsertGrowableList(&cUnit->pcReconstructionList, (intptr_t) pcrLabel);
/* Branch to the PC reconstruction code */
branch->generic.target = (LIR *) pcrLabel;
}
@@ -1156,12 +1156,13 @@ static void genInvokeVirtualCommon(CompilationUnit *cUnit, MIR *mir,
*/
if (pcrLabel == NULL) {
int dPC = (int) (cUnit->method->insns + mir->offset);
- pcrLabel = dvmCompilerNew(sizeof(ArmLIR), true);
+ pcrLabel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
pcrLabel->opcode = kArmPseudoPCReconstructionCell;
pcrLabel->operands[0] = dPC;
pcrLabel->operands[1] = mir->offset;
/* Insert the place holder to the growable list */
- dvmInsertGrowableList(&cUnit->pcReconstructionList, pcrLabel);
+ dvmInsertGrowableList(&cUnit->pcReconstructionList,
+ (intptr_t) pcrLabel);
}
/* return through lr+2 - punt to the interpreter */
@@ -1480,7 +1481,7 @@ static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
isVolatile = (mir->dalvikInsn.opcode == OP_SGET_VOLATILE) ||
(mir->dalvikInsn.opcode == OP_SGET_OBJECT_VOLATILE) ||
- dvmIsVolatileField(fieldPtr);
+ dvmIsVolatileField((Field *) fieldPtr);
rlDest = dvmCompilerGetDest(cUnit, mir, 0);
rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
@@ -1540,7 +1541,7 @@ static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
isVolatile = (mir->dalvikInsn.opcode == OP_SPUT_VOLATILE) ||
(mir->dalvikInsn.opcode == OP_SPUT_OBJECT_VOLATILE) ||
- dvmIsVolatileField(fieldPtr);
+ dvmIsVolatileField((Field *) fieldPtr);
isSputObject = (mir->dalvikInsn.opcode == OP_SPUT_OBJECT) ||
(mir->dalvikInsn.opcode == OP_SPUT_OBJECT_VOLATILE);
@@ -1599,7 +1600,7 @@ static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
* Obey the calling convention and don't mess with the register
* usage.
*/
- ClassObject *classPtr = (void*)
+ ClassObject *classPtr = (ClassObject *)
(cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vB]);
if (classPtr == NULL) {
@@ -3007,12 +3008,13 @@ static bool handleFmt35c_3rc(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
*/
if (pcrLabel == NULL) {
int dPC = (int) (cUnit->method->insns + mir->offset);
- pcrLabel = dvmCompilerNew(sizeof(ArmLIR), true);
+ pcrLabel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
pcrLabel->opcode = kArmPseudoPCReconstructionCell;
pcrLabel->operands[0] = dPC;
pcrLabel->operands[1] = mir->offset;
/* Insert the place holder to the growable list */
- dvmInsertGrowableList(&cUnit->pcReconstructionList, pcrLabel);
+ dvmInsertGrowableList(&cUnit->pcReconstructionList,
+ (intptr_t) pcrLabel);
}
/* return through lr+2 - punt to the interpreter */
@@ -3532,7 +3534,6 @@ static void handleHotChainingCell(CompilationUnit *cUnit,
addWordData(cUnit, (int) (cUnit->method->insns + offset), true);
}
-#if defined(WITH_SELF_VERIFICATION) || defined(WITH_JIT_TUNING)
/* Chaining cell for branches that branch back into the same basic block */
static void handleBackwardBranchChainingCell(CompilationUnit *cUnit,
unsigned int offset)
@@ -3554,7 +3555,6 @@ static void handleBackwardBranchChainingCell(CompilationUnit *cUnit,
addWordData(cUnit, (int) (cUnit->method->insns + offset), true);
}
-#endif
/* Chaining cell for monomorphic method invocations. */
static void handleInvokeSingletonChainingCell(CompilationUnit *cUnit,
const Method *callee)
@@ -3830,8 +3830,8 @@ static void genValidationForPredictedInline(CompilationUnit *cUnit, MIR *mir)
static void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir)
{
int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
- char *msg = dvmCompilerNew(strlen(extendedMIROpNames[opOffset]) + 1,
- false);
+ char *msg = (char *)dvmCompilerNew(strlen(extendedMIROpNames[opOffset]) + 1,
+ false);
strcpy(msg, extendedMIROpNames[opOffset]);
newLIR1(cUnit, kArmPseudoExtended, (int) msg);
@@ -3878,25 +3878,25 @@ static void setupLoopEntryBlock(CompilationUnit *cUnit, BasicBlock *entry,
ArmLIR *bodyLabel)
{
/* Set up the place holder to reconstruct this Dalvik PC */
- ArmLIR *pcrLabel = dvmCompilerNew(sizeof(ArmLIR), true);
+ ArmLIR *pcrLabel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
pcrLabel->opcode = kArmPseudoPCReconstructionCell;
pcrLabel->operands[0] =
(int) (cUnit->method->insns + entry->startOffset);
pcrLabel->operands[1] = entry->startOffset;
/* Insert the place holder to the growable list */
- dvmInsertGrowableList(&cUnit->pcReconstructionList, pcrLabel);
+ dvmInsertGrowableList(&cUnit->pcReconstructionList, (intptr_t) pcrLabel);
/*
* Next, create two branches - one branch over to the loop body and the
* other branch to the PCR cell to punt.
*/
- ArmLIR *branchToBody = dvmCompilerNew(sizeof(ArmLIR), true);
+ ArmLIR *branchToBody = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
branchToBody->opcode = kThumbBUncond;
branchToBody->generic.target = (LIR *) bodyLabel;
setupResourceMasks(branchToBody);
cUnit->loopAnalysis->branchToBody = (LIR *) branchToBody;
- ArmLIR *branchToPCR = dvmCompilerNew(sizeof(ArmLIR), true);
+ ArmLIR *branchToPCR = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true);
branchToPCR->opcode = kThumbBUncond;
branchToPCR->generic.target = (LIR *) pcrLabel;
setupResourceMasks(branchToPCR);
@@ -3926,7 +3926,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
{
/* Used to hold the labels of each block */
ArmLIR *labelList =
- dvmCompilerNew(sizeof(ArmLIR) * cUnit->numBlocks, true);
+ (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR) * cUnit->numBlocks, true);
GrowableList chainingListByType[kChainingCellGap];
int i;
@@ -3937,51 +3937,22 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
dvmInitGrowableList(&chainingListByType[i], 2);
}
- BasicBlock **blockList = cUnit->blockList;
+ GrowableListIterator iterator;
+ dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
- if (cUnit->executionCount) {
- /*
- * Reserve 6 bytes at the beginning of the trace
- * +----------------------------+
- * | execution count (4 bytes) |
- * +----------------------------+
- * | chain cell offset (2 bytes)|
- * +----------------------------+
- * ...and then code to increment the execution
- * count:
- * mov r0, pc @ move adr of "mov r0,pc" + 4 to r0
- * sub r0, #10 @ back up to addr of executionCount
- * ldr r1, [r0]
- * add r1, #1
- * str r1, [r0]
- */
- newLIR1(cUnit, kArm16BitData, 0);
- newLIR1(cUnit, kArm16BitData, 0);
- cUnit->chainCellOffsetLIR =
- (LIR *) newLIR1(cUnit, kArm16BitData, CHAIN_CELL_OFFSET_TAG);
- cUnit->headerSize = 6;
- /* Thumb instruction used directly here to ensure correct size */
- newLIR2(cUnit, kThumbMovRR_H2L, r0, rpc);
- newLIR2(cUnit, kThumbSubRI8, r0, 10);
- newLIR3(cUnit, kThumbLdrRRI5, r1, r0, 0);
- newLIR2(cUnit, kThumbAddRI8, r1, 1);
- newLIR3(cUnit, kThumbStrRRI5, r1, r0, 0);
- } else {
- /* Just reserve 2 bytes for the chain cell offset */
- cUnit->chainCellOffsetLIR =
- (LIR *) newLIR1(cUnit, kArm16BitData, CHAIN_CELL_OFFSET_TAG);
- cUnit->headerSize = 2;
- }
+ /* Traces start with a profiling entry point. Generate it here */
+ cUnit->profileCodeSize = genTraceProfileEntry(cUnit);
/* Handle the content in each basic block */
- for (i = 0; i < cUnit->numBlocks; i++) {
- blockList[i]->visited = true;
+ for (i = 0; ; i++) {
MIR *mir;
+ BasicBlock *bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
+ if (bb == NULL) break;
- labelList[i].operands[0] = blockList[i]->startOffset;
+ labelList[i].operands[0] = bb->startOffset;
- if (blockList[i]->blockType >= kChainingCellGap) {
- if (blockList[i]->isFallThroughFromInvoke == true) {
+ if (bb->blockType >= kChainingCellGap) {
+ if (bb->isFallThroughFromInvoke == true) {
/* Align this block first since it is a return chaining cell */
newLIR0(cUnit, kArmPseudoPseudoAlign4);
}
@@ -3992,56 +3963,53 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[i]);
}
- if (blockList[i]->blockType == kTraceEntryBlock) {
+ if (bb->blockType == kTraceEntryBlock) {
labelList[i].opcode = kArmPseudoEntryBlock;
- if (blockList[i]->firstMIRInsn == NULL) {
+ if (bb->firstMIRInsn == NULL) {
continue;
} else {
- setupLoopEntryBlock(cUnit, blockList[i],
- &labelList[blockList[i]->fallThrough->id]);
+ setupLoopEntryBlock(cUnit, bb,
+ &labelList[bb->fallThrough->id]);
}
- } else if (blockList[i]->blockType == kTraceExitBlock) {
+ } else if (bb->blockType == kTraceExitBlock) {
labelList[i].opcode = kArmPseudoExitBlock;
goto gen_fallthrough;
- } else if (blockList[i]->blockType == kDalvikByteCode) {
+ } else if (bb->blockType == kDalvikByteCode) {
labelList[i].opcode = kArmPseudoNormalBlockLabel;
/* Reset the register state */
dvmCompilerResetRegPool(cUnit);
dvmCompilerClobberAllRegs(cUnit);
dvmCompilerResetNullCheck(cUnit);
} else {
- switch (blockList[i]->blockType) {
+ switch (bb->blockType) {
case kChainingCellNormal:
labelList[i].opcode = kArmPseudoChainingCellNormal;
/* handle the codegen later */
dvmInsertGrowableList(
- &chainingListByType[kChainingCellNormal], (void *) i);
+ &chainingListByType[kChainingCellNormal], i);
break;
case kChainingCellInvokeSingleton:
labelList[i].opcode =
kArmPseudoChainingCellInvokeSingleton;
labelList[i].operands[0] =
- (int) blockList[i]->containingMethod;
+ (int) bb->containingMethod;
/* handle the codegen later */
dvmInsertGrowableList(
- &chainingListByType[kChainingCellInvokeSingleton],
- (void *) i);
+ &chainingListByType[kChainingCellInvokeSingleton], i);
break;
case kChainingCellInvokePredicted:
labelList[i].opcode =
kArmPseudoChainingCellInvokePredicted;
/* handle the codegen later */
dvmInsertGrowableList(
- &chainingListByType[kChainingCellInvokePredicted],
- (void *) i);
+ &chainingListByType[kChainingCellInvokePredicted], i);
break;
case kChainingCellHot:
labelList[i].opcode =
kArmPseudoChainingCellHot;
/* handle the codegen later */
dvmInsertGrowableList(
- &chainingListByType[kChainingCellHot],
- (void *) i);
+ &chainingListByType[kChainingCellHot], i);
break;
case kPCReconstruction:
/* Make sure exception handling block is next */
@@ -4059,16 +4027,14 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
opReg(cUnit, kOpBlx, r1);
}
break;
-#if defined(WITH_SELF_VERIFICATION) || defined(WITH_JIT_TUNING)
case kChainingCellBackwardBranch:
labelList[i].opcode =
kArmPseudoChainingCellBackwardBranch;
/* handle the codegen later */
dvmInsertGrowableList(
&chainingListByType[kChainingCellBackwardBranch],
- (void *) i);
+ i);
break;
-#endif
default:
break;
}
@@ -4077,7 +4043,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
ArmLIR *headLIR = NULL;
- for (mir = blockList[i]->firstMIRInsn; mir; mir = mir->next) {
+ for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
dvmCompilerResetRegPool(cUnit);
if (gDvmJit.disableOpt & (1 << kTrackLiveTemps)) {
@@ -4145,7 +4111,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
case kFmt20t:
case kFmt30t:
notHandled = handleFmt10t_Fmt20t_Fmt30t(cUnit,
- mir, blockList[i], labelList);
+ mir, bb, labelList);
break;
case kFmt10x:
notHandled = handleFmt10x(cUnit, mir);
@@ -4174,8 +4140,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
notHandled = handleFmt21s(cUnit, mir);
break;
case kFmt21t:
- notHandled = handleFmt21t(cUnit, mir, blockList[i],
- labelList);
+ notHandled = handleFmt21t(cUnit, mir, bb, labelList);
break;
case kFmt22b:
case kFmt22s:
@@ -4188,8 +4153,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
notHandled = handleFmt22cs(cUnit, mir);
break;
case kFmt22t:
- notHandled = handleFmt22t(cUnit, mir, blockList[i],
- labelList);
+ notHandled = handleFmt22t(cUnit, mir, bb, labelList);
break;
case kFmt22x:
case kFmt32x:
@@ -4203,12 +4167,12 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
break;
case kFmt3rc:
case kFmt35c:
- notHandled = handleFmt35c_3rc(cUnit, mir, blockList[i],
+ notHandled = handleFmt35c_3rc(cUnit, mir, bb,
labelList);
break;
case kFmt3rms:
case kFmt35ms:
- notHandled = handleFmt35ms_3rms(cUnit, mir,blockList[i],
+ notHandled = handleFmt35ms_3rms(cUnit, mir, bb,
labelList);
break;
case kFmt35mi:
@@ -4233,7 +4197,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
}
}
- if (blockList[i]->blockType == kTraceEntryBlock) {
+ if (bb->blockType == kTraceEntryBlock) {
dvmCompilerAppendLIR(cUnit,
(LIR *) cUnit->loopAnalysis->branchToBody);
dvmCompilerAppendLIR(cUnit,
@@ -4254,9 +4218,9 @@ gen_fallthrough:
* Check if the block is terminated due to trace length constraint -
* insert an unconditional branch to the chaining cell.
*/
- if (blockList[i]->needFallThroughBranch) {
+ if (bb->needFallThroughBranch) {
genUnconditionalBranch(cUnit,
- &labelList[blockList[i]->fallThrough->id]);
+ &labelList[bb->fallThrough->id]);
}
}
@@ -4277,6 +4241,9 @@ gen_fallthrough:
for (j = 0; j < chainingListByType[i].numUsed; j++) {
int blockId = blockIdList[j];
+ BasicBlock *chainingBlock =
+ (BasicBlock *) dvmGrowableListGetElement(&cUnit->blockList,
+ blockId);
/* Align this chaining cell first */
newLIR0(cUnit, kArmPseudoPseudoAlign4);
@@ -4285,30 +4252,26 @@ gen_fallthrough:
dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[blockId]);
- switch (blockList[blockId]->blockType) {
+ switch (chainingBlock->blockType) {
case kChainingCellNormal:
- handleNormalChainingCell(cUnit,
- blockList[blockId]->startOffset);
+ handleNormalChainingCell(cUnit, chainingBlock->startOffset);
break;
case kChainingCellInvokeSingleton:
handleInvokeSingletonChainingCell(cUnit,
- blockList[blockId]->containingMethod);
+ chainingBlock->containingMethod);
break;
case kChainingCellInvokePredicted:
handleInvokePredictedChainingCell(cUnit);
break;
case kChainingCellHot:
- handleHotChainingCell(cUnit,
- blockList[blockId]->startOffset);
+ handleHotChainingCell(cUnit, chainingBlock->startOffset);
break;
-#if defined(WITH_SELF_VERIFICATION) || defined(WITH_JIT_TUNING)
case kChainingCellBackwardBranch:
handleBackwardBranchChainingCell(cUnit,
- blockList[blockId]->startOffset);
+ chainingBlock->startOffset);
break;
-#endif
default:
- LOGE("Bad blocktype %d", blockList[blockId]->blockType);
+ LOGE("Bad blocktype %d", chainingBlock->blockType);
dvmCompilerAbort(cUnit);
}
}
@@ -4340,10 +4303,15 @@ gen_fallthrough:
#endif
}
-/* Accept the work and start compiling */
+/*
+ * Accept the work and start compiling. Returns true if compilation
+ * is attempted.
+ */
bool dvmCompilerDoWork(CompilerWorkOrder *work)
{
- bool res;
+ JitTraceDescription *desc;
+ bool isCompile;
+ bool success = true;
if (gDvmJit.codeCacheFull) {
return false;
@@ -4351,25 +4319,35 @@ bool dvmCompilerDoWork(CompilerWorkOrder *work)
switch (work->kind) {
case kWorkOrderTrace:
+ isCompile = true;
/* Start compilation with maximally allowed trace length */
- res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result,
- work->bailPtr, 0 /* no hints */);
+ desc = (JitTraceDescription *)work->info;
+ success = dvmCompileTrace(desc, JIT_MAX_TRACE_LEN, &work->result,
+ work->bailPtr, 0 /* no hints */);
break;
case kWorkOrderTraceDebug: {
bool oldPrintMe = gDvmJit.printMe;
gDvmJit.printMe = true;
+ isCompile = true;
/* Start compilation with maximally allowed trace length */
- res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result,
- work->bailPtr, 0 /* no hints */);
+ desc = (JitTraceDescription *)work->info;
+ success = dvmCompileTrace(desc, JIT_MAX_TRACE_LEN, &work->result,
+ work->bailPtr, 0 /* no hints */);
gDvmJit.printMe = oldPrintMe;
break;
}
+ case kWorkOrderProfileMode:
+ dvmJitChangeProfileMode((TraceProfilingModes)work->info);
+ isCompile = false;
+ break;
default:
- res = false;
+ isCompile = false;
LOGE("Jit: unknown work order type");
assert(0); // Bail if debug build, discard otherwise
}
- return res;
+ if (!success)
+ work->result.codeAddress = NULL;
+ return isCompile;
}
/* Architectural-specific debugging helpers go here */