diff options
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenDriver.c')
| -rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 188 |
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 */ |
