diff options
Diffstat (limited to 'src/compiler/codegen/arm')
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmRallocUtil.cc | 5 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Assemble.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/MethodCodegenDriver.cc | 39 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 95 |
5 files changed, 68 insertions, 79 deletions
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h index 99b22e7741..daa13962c0 100644 --- a/src/compiler/codegen/arm/ArmLIR.h +++ b/src/compiler/codegen/arm/ArmLIR.h @@ -357,8 +357,6 @@ typedef enum ArmThrowKind { kArmThrowArrayBounds, kArmThrowVerificationError, kArmThrowNegArraySize, - kArmThrowInternalError, - kArmThrowRuntimeException, kArmThrowNoSuchMethod, kArmThrowStackOverflow, } ArmThrowKind; diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc index 9a7c642aee..94852e391f 100644 --- a/src/compiler/codegen/arm/ArmRallocUtil.cc +++ b/src/compiler/codegen/arm/ArmRallocUtil.cc @@ -178,11 +178,6 @@ extern void oatDoPromotion(CompilationUnit* cUnit) qsort(coreRegs, numRegs, sizeof(RefCounts), sortCounts); qsort(fpRegs, numRegs, sizeof(RefCounts), sortCounts); - if (cUnit->printMeVerbose) { - dumpCounts(coreRegs, numRegs, "coreRegs"); - dumpCounts(fpRegs, numRegs, "fpRegs"); - } - if (!(cUnit->disableOpt & (1 << kPromoteRegs))) { // Promote fpRegs for (int i = 0; (fpRegs[i].count > 0) && (i < numRegs); i++) { diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc index c42b4b8b93..bbd97b4d75 100644 --- a/src/compiler/codegen/arm/Assemble.cc +++ b/src/compiler/codegen/arm/Assemble.cc @@ -20,12 +20,6 @@ #include "Codegen.h" #include <sys/mman.h> /* for protection change */ -//#define TESTMODE -#ifdef TESTMODE -#include <cutils/ashmem.h> /* for oat testing */ -#include <unistd.h> -#endif - #define MAX_ASSEMBLER_RETRIES 50 /* diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc index 6be9f761e7..922e25b4e6 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -14,7 +14,8 @@ * limitations under the License. */ -#define DISPLAY_MISSING_TARGETS 1 +#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \ + (1 << kDebugDisplayMissingTargets)) STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, INVALID_REG, INVALID_REG, INVALID_SREG, 0, @@ -922,7 +923,6 @@ STATIC int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir, return callState; } -#ifdef DISPLAY_MISSING_TARGETS // Debugging routine - if null target, branch to DebugMe STATIC void genShowTarget(CompilationUnit* cUnit) { @@ -933,7 +933,6 @@ STATIC void genShowTarget(CompilationUnit* cUnit) target->defMask = -1; branchOver->generic.target = (LIR*)target; } -#endif STATIC void genInvokeStaticDirect(CompilationUnit* cUnit, MIR* mir, bool direct, bool range) @@ -959,9 +958,9 @@ STATIC void genInvokeStaticDirect(CompilationUnit* cUnit, MIR* mir, while (callState >= 0) { callState = nextCallInsn(cUnit, mir, dInsn, callState, NULL); } -#ifdef DISPLAY_MISSING_TARGETS - genShowTarget(cUnit); -#endif + if (DISPLAY_MISSING_TARGETS) { + genShowTarget(cUnit); + } opReg(cUnit, kOpBlx, rLR); oatClobberCalleeSave(cUnit); } @@ -992,9 +991,9 @@ STATIC void genInvokeInterface(CompilationUnit* cUnit, MIR* mir) while (callState >= 0) { callState = nextInterfaceCallInsn(cUnit, mir, dInsn, callState, NULL); } -#ifdef DISPLAY_MISSING_TARGETS - genShowTarget(cUnit); -#endif + if (DISPLAY_MISSING_TARGETS) { + genShowTarget(cUnit); + } opReg(cUnit, kOpBlx, rLR); oatClobberCalleeSave(cUnit); } @@ -1045,9 +1044,9 @@ STATIC void genInvokeSuper(CompilationUnit* cUnit, MIR* mir) while (callState >= 0) { callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback); } -#ifdef DISPLAY_MISSING_TARGETS - genShowTarget(cUnit); -#endif + if (DISPLAY_MISSING_TARGETS) { + genShowTarget(cUnit); + } opReg(cUnit, kOpBlx, rLR); oatClobberCalleeSave(cUnit); } @@ -1085,9 +1084,9 @@ STATIC void genInvokeVirtual(CompilationUnit* cUnit, MIR* mir) while (callState >= 0) { callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback); } -#ifdef DISPLAY_MISSING_TARGETS - genShowTarget(cUnit); -#endif + if (DISPLAY_MISSING_TARGETS) { + genShowTarget(cUnit); + } opReg(cUnit, kOpBlx, rLR); oatClobberCalleeSave(cUnit); } @@ -2108,16 +2107,6 @@ STATIC void handleThrowLaunchpads(CompilationUnit *cUnit) funcOffset = OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode); break; - case kArmThrowInternalError: - genRegCopy(cUnit, r0, v1); - funcOffset = - OFFSETOF_MEMBER(Thread, pThrowInternalErrorFromCode); - break; - case kArmThrowRuntimeException: - genRegCopy(cUnit, r0, v1); - funcOffset = - OFFSETOF_MEMBER(Thread, pThrowRuntimeExceptionFromCode); - break; case kArmThrowNoSuchMethod: genRegCopy(cUnit, r0, v1); funcOffset = diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index 3f7a7aef53..b63c37fdb2 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -22,9 +22,16 @@ * */ -#define SLOW_FIELD_PATH 0 -#define SLOW_INVOKE_PATH 0 -//#define EXERCISE_SLOWEST_FIELD_PATH +#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath)) +#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath)) +#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath)) +#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath)) +#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \ + (1 << kDebugSlowestFieldPath)) +#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \ + (1 << kDebugSlowestStringPath)) + +STATIC RegLocation getRetLoc(CompilationUnit* cUnit); std::string fieldNameFromIndex(const Method* method, uint32_t fieldIdx) { @@ -427,9 +434,10 @@ STATIC void getFieldOffset(CompilationUnit* cUnit, MIR* mir, Field* fieldPtr) * For testing, omit the test for run-time resolution. This will * force all accesses to go through the runtime resolution path. */ -#ifndef EXERCISE_SLOWEST_FIELD_PATH - ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0); -#endif + ArmLIR* branchOver = NULL; + if (!EXERCISE_SLOWEST_FIELD_PATH) { + branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0); + } // Resolve loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pFindInstanceFieldFromCode), rLR); @@ -437,9 +445,9 @@ STATIC void getFieldOffset(CompilationUnit* cUnit, MIR* mir, Field* fieldPtr) callRuntimeHelper(cUnit, rLR); // resolveTypeFromCode(idx, method) ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel); target->defMask = ENCODE_ALL; -#ifndef EXERCISE_SLOWEST_FIELD_PATH - branchOver->generic.target = (LIR*)target; -#endif + if (!EXERCISE_SLOWEST_FIELD_PATH) { + branchOver->generic.target = (LIR*)target; + } // Free temps (except for r0) oatFreeTemp(cUnit, r1); oatFreeTemp(cUnit, r2); @@ -532,7 +540,7 @@ STATIC void genIGetWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, #else bool isVolatile = false; #endif - if ((fieldPtr == NULL) || isVolatile) { + if (SLOW_FIELD_PATH || (fieldPtr == NULL) || isVolatile) { getFieldOffset(cUnit, mir, fieldPtr); // Field offset in r0 rlObj = loadValue(cUnit, rlObj, kCoreReg); @@ -570,7 +578,7 @@ STATIC void genIPutWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc, #else bool isVolatile = false; #endif - if ((fieldPtr == NULL) || isVolatile) { + if (SLOW_FIELD_PATH || (fieldPtr == NULL) || isVolatile) { getFieldOffset(cUnit, mir, fieldPtr); // Field offset in r0 rlObj = loadValue(cUnit, rlObj, kCoreReg); @@ -607,7 +615,7 @@ STATIC void genConstClass(CompilationUnit* cUnit, MIR* mir, resReg); loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() + (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg); - if (classPtr != NULL) { + if (SLOW_TYPE_PATH || (classPtr == NULL)) { // Fast path, we're done - just store result storeValue(cUnit, rlDest, rlResult); } else { @@ -640,19 +648,41 @@ STATIC void genConstClass(CompilationUnit* cUnit, MIR* mir, STATIC void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, RegLocation rlSrc) { - /* All strings should be available at compile time */ + /* NOTE: Most strings should be available at compile time */ const art::String* str = cUnit->method->GetDexCacheStrings()-> Get(mir->dalvikInsn.vB); - DCHECK(str != NULL); - - int mReg = loadCurrMethod(cUnit); - int resReg = oatAllocTemp(cUnit); - RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); - loadWordDisp(cUnit, mReg, Method::DexCacheStringsOffset().Int32Value(), - resReg); - loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() + - (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg); - storeValue(cUnit, rlDest, rlResult); + if (SLOW_STRING_PATH || (str == NULL)) { + oatFlushAllRegs(cUnit); + oatLockCallTemps(cUnit); // Using explicit registers + loadCurrMethodDirect(cUnit, r2); + loadWordDisp(cUnit, r2, Method::DexCacheStringsOffset().Int32Value(), + r0); + // Might call out to helper, which will return resolved string in r0 + loadWordDisp(cUnit, rSELF, + OFFSETOF_MEMBER(Thread, pResolveStringFromCode), rLR); + loadWordDisp(cUnit, r0, Array::DataOffset().Int32Value() + + (sizeof(String*) * mir->dalvikInsn.vB), r0); + loadConstant(cUnit, r1, mir->dalvikInsn.vB); + opRegImm(cUnit, kOpCmp, r0, 0); // Is resolved? + genBarrier(cUnit); + // For testing, always force through helper + if (!EXERCISE_SLOWEST_STRING_PATH) { + genIT(cUnit, kArmCondEq, "T"); + } + genRegCopy(cUnit, r0, r2); // .eq + opReg(cUnit, kOpBlx, rLR); // .eq, helper(Method*, string_idx) + genBarrier(cUnit); + storeValue(cUnit, rlDest, getRetLoc(cUnit)); + } else { + int mReg = loadCurrMethod(cUnit); + int resReg = oatAllocTemp(cUnit); + RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); + loadWordDisp(cUnit, mReg, Method::DexCacheStringsOffset().Int32Value(), + resReg); + loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() + + (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg); + storeValue(cUnit, rlDest, rlResult); + } } /* @@ -1778,25 +1808,8 @@ STATIC void genSuspendPoll(CompilationUnit* cUnit, MIR* mir) OFFSETOF_MEMBER(Thread, pCheckSuspendFromCode), rLR); genRegCopy(cUnit, r0, rSELF); opRegImm(cUnit, kOpCmp, rSuspendCount, 0); - /* - * FIXME: for efficiency we should use an if-converted suspend - * test here. However, support for IT is a bit weak at the - * moment, and requires knowledge of the exact number of instructions - * to fall in the skip shadow. While the exception mechanism - * remains in flux, use a compare and branch sequence. Once - * things firm up, restore the conditional skip (and perhaps - * fix the utility to handle variable-sized shadows). - */ -#if 0 genIT(cUnit, kArmCondNe, ""); - callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self) -#else - ArmLIR* branch = opCondBranch(cUnit, kArmCondEq); - callRuntimeHelper(cUnit, rLR); // CheckSuspendFromCode(self) - ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel); - target->defMask = ENCODE_ALL; - branch->generic.target = (LIR*)target; -#endif + opReg(cUnit, kOpBlx, rLR); oatFreeCallTemps(cUnit); } |