diff options
| -rw-r--r-- | src/asm_support.h | 6 | ||||
| -rw-r--r-- | src/compiler/Compiler.h | 33 | ||||
| -rw-r--r-- | src/compiler/CompilerIR.h | 5 | ||||
| -rw-r--r-- | src/compiler/Dataflow.cc | 4 | ||||
| -rw-r--r-- | src/compiler/Frontend.cc | 66 | ||||
| -rw-r--r-- | src/compiler/codegen/Optimizer.h | 10 | ||||
| -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 | ||||
| -rw-r--r-- | src/runtime_support.h | 2 | ||||
| -rw-r--r-- | src/runtime_support_asm.S | 16 | ||||
| -rw-r--r-- | src/thread.cc | 9 | ||||
| -rw-r--r-- | src/thread.h | 3 |
15 files changed, 152 insertions, 149 deletions
diff --git a/src/asm_support.h b/src/asm_support.h index 1ef10b8645..32c3abefe5 100644 --- a/src/asm_support.h +++ b/src/asm_support.h @@ -9,13 +9,13 @@ #define rLR r14 #define SUSPEND_CHECK_INTERVAL (1000) // Offset of field Thread::top_of_managed_stack_ verified in InitCpu -#define THREAD_TOP_OF_MANAGED_STACK_OFFSET 276 +#define THREAD_TOP_OF_MANAGED_STACK_OFFSET 272 // Offset of field Thread::top_of_managed_stack_pc_ verified in InitCpu -#define THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET 280 +#define THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET 276 #elif defined(__i386__) // Offset of field Thread::self_ verified in InitCpu -#define THREAD_SELF_OFFSET 372 +#define THREAD_SELF_OFFSET 368 #endif #endif // ART_SRC_ASM_SUPPORT_H_ diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h index ba97aac6e7..f9e2478e47 100644 --- a/src/compiler/Compiler.h +++ b/src/compiler/Compiler.h @@ -26,6 +26,39 @@ typedef enum OatInstructionSetType { DALVIK_OAT_THUMB2, } OatInstructionSetType; +/* Supress optimization if corresponding bit set */ +enum optControlVector { + kLoadStoreElimination = 0, + kLoadHoisting, + kSuppressLoads, + kNullCheckElimination, + kPromoteRegs, + kTrackLiveTemps, +}; + +extern uint32_t compilerOptimizerDisableFlags; + +/* Force code generation paths for testing */ +enum debugControlVector { + kDebugDisplayMissingTargets, + kDebugVerbose, + kDebugDumpCFG, + kDebugSlowFieldPath, + kDebugSlowInvokePath, + kDebugSlowStringPath, + kDebugSlowTypePath, + kDebugSlowestFieldPath, + kDebugSlowestStringPath, +}; + +extern uint32_t compilerDebugFlags; + +/* If non-empty, apply optimizer/debug flags only to matching methods */ +extern std::string compilerMethodMatch; + +/* Flips sense of compilerMethodMatch - apply flags if doesn't match */ +extern bool compilerFlipMatch; + typedef enum OatMethodAttributes { kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */ kIsHot, /* Code is part of a hot trace */ diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h index 2d4f83e93d..14af69d3d6 100644 --- a/src/compiler/CompilerIR.h +++ b/src/compiler/CompilerIR.h @@ -192,7 +192,8 @@ typedef struct CompilationUnit { LIR* classPointerList; // Relocatable int numClassPointers; LIR* chainCellOffsetLIR; - int disableOpt; + uint32_t disableOpt; // optControlVector flags + uint32_t enableDebug; // debugControlVector flags int headerSize; // bytes before the first code ptr int dataOffset; // starting offset of literal pool int totalSize; // header + code size @@ -203,8 +204,6 @@ typedef struct CompilationUnit { std::vector<uint32_t> coreVmapTable; std::vector<short> fpVmapTable; bool printMe; - bool printMeVerbose; - bool dumpCFG; bool hasClassLiterals; // Contains class ptrs used as literals bool hasLoop; // Contains a loop bool hasInvoke; // Contains an invoke instruction diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc index 65aa6d8253..0713554413 100644 --- a/src/compiler/Dataflow.cc +++ b/src/compiler/Dataflow.cc @@ -1987,10 +1987,6 @@ bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb) if (bb->dataFlowInfo == NULL) return false; - if (cUnit->printMeVerbose) { - LOG(INFO) << "oatDoSSAConversion processing block " << bb->id; - } - for (mir = bb->firstMIRInsn; mir; mir = mir->next) { mir->ssaRep = (struct SSARepresentation *) oatNew(sizeof(SSARepresentation), true); diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc index cb831438a7..ebbd72f79c 100644 --- a/src/compiler/Frontend.cc +++ b/src/compiler/Frontend.cc @@ -21,6 +21,33 @@ #include "object.h" #include "runtime.h" +/* Default optimizer/debug setting for the compiler. */ +uint32_t compilerOptimizerDisableFlags = 0 | // Disable specific optimizations + // TODO: enable all of these by default in ToT + (1 << kLoadStoreElimination) | + (1 << kLoadHoisting) | + (1 << kSuppressLoads) | + (1 << kNullCheckElimination) | + (1 << kPromoteRegs) | + (1 << kTrackLiveTemps) | + 0; + +uint32_t compilerDebugFlags = 0 | // Enable debug/testing modes + // TODO: disable all of these by default in ToT + (1 << kDebugDisplayMissingTargets) | + //(1 << kDebugVerbose) | + //(1 << kDebugDumpCFG) | + //(1 << kDebugSlowFieldPath) | + //(1 << kDebugSlowInvokePath) | + //(1 << kDebugSlowStringPath) | + //(1 << kDebugSlowestFieldPath) | + //(1 << kDebugSlowestStringPath) | + 0; + +std::string compilerMethodMatch; // Method name match to apply above flags + +bool compilerFlipMatch = false; // Reverses sense of method name match + STATIC inline bool contentIsInsn(const u2* codePtr) { u2 instr = *codePtr; Opcode opcode = (Opcode)(instr & 0xff); @@ -329,10 +356,7 @@ void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix) } fprintf(file, "\n"); - /* - * If we need to debug the dominator tree, uncomment the following code - */ -#if 1 + /* Display the dominator tree */ oatGetBlockName(bb, blockName1); fprintf(file, " cfg%s [label=\"%s\", shape=none];\n", blockName1, blockName1); @@ -341,7 +365,6 @@ void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix) fprintf(file, " cfg%s:s -> cfg%s:n\n\n", blockName2, blockName1); } -#endif } fprintf(file, "}\n"); fclose(file); @@ -687,29 +710,22 @@ bool oatCompileMethod(const Compiler& compiler, Method* method, art::Instruction int numBlocks = 0; unsigned int curOffset = 0; -#if 1 - // FIXME - temp 'till properly integrated oatInit(compiler); -#endif memset(&cUnit, 0, sizeof(cUnit)); cUnit.method = method; cUnit.instructionSet = (OatInstructionSetType)insnSet; cUnit.insns = code_item->insns_; cUnit.insnsSize = code_item->insns_size_; -#if 1 - // TODO: Use command-line argument passing mechanism - cUnit.printMe = compiler.IsVerbose(); - cUnit.printMeVerbose = compiler.IsVerbose(); - cUnit.disableOpt = 0 | - (1 << kTrackLiveTemps) | - (1 << kLoadStoreElimination) | - (1 << kLoadHoisting) | - (1 << kSuppressLoads) | - (1 << kNullCheckElimination) | - (1 << kPromoteRegs) | - 0; -#endif + bool useMatch = compilerMethodMatch.length() != 0; + bool match = useMatch && (compilerFlipMatch ^ + (PrettyMethod(method).find(compilerMethodMatch) != std::string::npos)); + if (!useMatch || match) { + cUnit.disableOpt = compilerOptimizerDisableFlags; + cUnit.enableDebug = compilerDebugFlags; + cUnit.printMe = compiler.IsVerbose() || + (cUnit.enableDebug & (1 << kDebugVerbose)); + } /* Assume non-throwing leaf */ cUnit.attrs = (METHOD_IS_LEAF | METHOD_IS_THROW_FREE); @@ -861,7 +877,7 @@ bool oatCompileMethod(const Compiler& compiler, Method* method, art::Instruction oatMethodMIR2LIR(&cUnit); // Debugging only - if (cUnit.dumpCFG) { + if (cUnit.enableDebug & (1 << kDebugDumpCFG)) { oatDumpCFG(&cUnit, "/sdcard/cfg/"); } @@ -916,17 +932,12 @@ bool oatCompileMethod(const Compiler& compiler, Method* method, art::Instruction << " code at " << reinterpret_cast<void*>(managed_code->GetData()) << " (" << managed_code->GetLength() << " bytes)"; } -#if 0 - oatDumpCFG(&cUnit, "/sdcard/cfg/"); -#endif return true; } void oatInit(const Compiler& compiler) { -#if 1 - // FIXME - temp hack 'till properly integrated static bool initialized = false; if (initialized) return; @@ -934,7 +945,6 @@ void oatInit(const Compiler& compiler) if (compiler.IsVerbose()) { LOG(INFO) << "Initializing compiler"; } -#endif if (!oatArchInit()) { LOG(FATAL) << "Failed to initialize oat"; } diff --git a/src/compiler/codegen/Optimizer.h b/src/compiler/codegen/Optimizer.h index c946e93fb2..307d401ff2 100644 --- a/src/compiler/codegen/Optimizer.h +++ b/src/compiler/codegen/Optimizer.h @@ -22,16 +22,6 @@ #define STACK_ALIGN_WORDS 4 #define STACK_ALIGNMENT (STACK_ALIGN_WORDS * 4) -/* Supress optimization if corresponding bit set */ -enum optControlVector { - kLoadStoreElimination = 0, - kLoadHoisting, - kSuppressLoads, - kNullCheckElimination, - kPromoteRegs, - kTrackLiveTemps, -}; - /* Forward declarations */ struct CompilationUnit; struct LIR; 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); } diff --git a/src/runtime_support.h b/src/runtime_support.h index 985074ce24..740047dca4 100644 --- a/src/runtime_support.h +++ b/src/runtime_support.h @@ -39,11 +39,9 @@ extern "C" void art_deliver_exception_from_code(void*); extern "C" void art_test_suspend(); extern "C" void art_throw_array_bounds_from_code(int32_t index, int32_t limit); extern "C" void art_throw_div_zero_from_code(); - extern "C" void art_throw_internal_error_from_code(int32_t errnum); extern "C" void art_throw_neg_array_size_from_code(int32_t size); extern "C" void art_throw_no_such_method_from_code(int32_t method_idx); extern "C" void art_throw_null_pointer_exception_from_code(); - extern "C" void art_throw_runtime_exception_from_code(int32_t errnum); extern "C" void art_throw_stack_overflow_from_code(void*); extern "C" void art_throw_verification_error_from_code(int32_t src1, int32_t ref); extern "C" void art_unlock_object_from_code(void*, void*); diff --git a/src/runtime_support_asm.S b/src/runtime_support_asm.S index eb12854981..7d4c906156 100644 --- a/src/runtime_support_asm.S +++ b/src/runtime_support_asm.S @@ -77,14 +77,6 @@ art_throw_neg_array_size_from_code: mov r2, sp @ pass SP b artThrowNegArraySizeFromCode @ artThrowNegArraySizeFromCode(size, Thread*, SP) - .global art_throw_internal_error_from_code - .extern artThrowInternalErrorFromCode -art_throw_internal_error_from_code: - SETUP_CALLEE_SAVE_FRAME - mov r1, r9 @ pass Thread::Current - mov r2, sp @ pass SP - b artThrowInternalErrorFromCode @ artThrowInternalErrorFromCode(errnum, Thread*, SP) - .global art_throw_no_such_method_from_code .extern artThrowNoSuchMethodFromCode art_throw_no_such_method_from_code: @@ -93,14 +85,6 @@ art_throw_no_such_method_from_code: mov r2, sp @ pass SP b artThrowNoSuchMethodFromCode @ artThrowNoSuchMethodFromCode(method_idx, Thread*, SP) - .global art_throw_runtime_exception_from_code - .extern artThrowRuntimeExceptionFromCode -art_throw_runtime_exception_from_code: - SETUP_CALLEE_SAVE_FRAME - mov r1, r9 @ pass Thread::Current - mov r2, sp @ pass SP - b artThrowRuntimeExceptionFromCode @ artThrowRuntimeExceptionFromCode(errnum, Thread*, SP) - .global art_throw_verification_error_from_code .extern artThrowVerificationErrorFromCode art_throw_verification_error_from_code: diff --git a/src/thread.cc b/src/thread.cc index 87a2017a44..29531f46a2 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -59,6 +59,12 @@ static Method* gThread_run = NULL; static Method* gThreadGroup_removeThread = NULL; static Method* gUncaughtExceptionHandler_uncaughtException = NULL; +// TODO: flesh out and move to appropriate location +String* ResolveStringFromCode(Method* method, int32_t string_idx) { + UNIMPLEMENTED(FATAL) << "Resolve string; handle OOM"; + return NULL; // Must return valid string or if exception, doesn't return +} + void Thread::InitFunctionPointers() { #if defined(__arm__) pShlLong = art_shl_long; @@ -96,11 +102,9 @@ void Thread::InitFunctionPointers() { pTestSuspendFromCode = art_test_suspend; pThrowArrayBoundsFromCode = art_throw_array_bounds_from_code; pThrowDivZeroFromCode = art_throw_div_zero_from_code; - pThrowInternalErrorFromCode = art_throw_internal_error_from_code; pThrowNegArraySizeFromCode = art_throw_neg_array_size_from_code; pThrowNoSuchMethodFromCode = art_throw_no_such_method_from_code; pThrowNullPointerFromCode = art_throw_null_pointer_exception_from_code; - pThrowRuntimeExceptionFromCode = art_throw_runtime_exception_from_code; pThrowStackOverflowFromCode = art_throw_stack_overflow_from_code; pThrowVerificationErrorFromCode = art_throw_verification_error_from_code; pUnlockObjectFromCode = art_unlock_object_from_code; @@ -124,6 +128,7 @@ void Thread::InitFunctionPointers() { pCheckSuspendFromCode = artCheckSuspendFromCode; pFindNativeMethod = FindNativeMethod; pDecodeJObjectInThread = DecodeJObjectInThread; + pResolveStringFromCode = ResolveStringFromCode; pDebugMe = DebugMe; } diff --git a/src/thread.h b/src/thread.h index c949339add..e1939c88bb 100644 --- a/src/thread.h +++ b/src/thread.h @@ -232,12 +232,11 @@ class PACKED Thread { void (*pThrowDivZeroFromCode)(); void (*pThrowVerificationErrorFromCode)(int32_t, int32_t); void (*pThrowNegArraySizeFromCode)(int32_t); - void (*pThrowRuntimeExceptionFromCode)(int32_t); - void (*pThrowInternalErrorFromCode)(int32_t); void (*pThrowNoSuchMethodFromCode)(int32_t); void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp); void* (*pFindNativeMethod)(Thread* thread); Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj); + String* (*pResolveStringFromCode)(Method*, int32_t); class StackVisitor { public: |