Compiler cleanup
o Added slow path for string resolution
o Removed dead throw internal and runtime error
o Restructured debug and optimization disable flags for make it easier
for command-line option support.
o Removed/converted #if 1/0 blocks
Change-Id: I65fc561a55437b3f74d0dfff5af87f938008d70e
diff --git a/src/asm_support.h b/src/asm_support.h
index 1ef10b8..32c3abe 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 ba97aac..f9e2478 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -26,6 +26,39 @@
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 2d4f83e..14af69d 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -192,7 +192,8 @@
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 @@
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 65aa6d8..0713554 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -1987,10 +1987,6 @@
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 cb83143..ebbd72f 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 @@
}
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 @@
fprintf(file, " cfg%s:s -> cfg%s:n\n\n",
blockName2, blockName1);
}
-#endif
}
fprintf(file, "}\n");
fclose(file);
@@ -687,29 +710,22 @@
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 @@
oatMethodMIR2LIR(&cUnit);
// Debugging only
- if (cUnit.dumpCFG) {
+ if (cUnit.enableDebug & (1 << kDebugDumpCFG)) {
oatDumpCFG(&cUnit, "/sdcard/cfg/");
}
@@ -916,17 +932,12 @@
<< " 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 @@
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 c946e93..307d401 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 99b22e7..daa1396 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -357,8 +357,6 @@
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 9a7c642..94852e3 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -178,11 +178,6 @@
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 c42b4b8..bbd97b4 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 6be9f76..922e25b 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 @@
return callState;
}
-#ifdef DISPLAY_MISSING_TARGETS
// Debugging routine - if null target, branch to DebugMe
STATIC void genShowTarget(CompilationUnit* cUnit)
{
@@ -933,7 +933,6 @@
target->defMask = -1;
branchOver->generic.target = (LIR*)target;
}
-#endif
STATIC void genInvokeStaticDirect(CompilationUnit* cUnit, MIR* mir,
bool direct, bool range)
@@ -959,9 +958,9 @@
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 @@
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 @@
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 @@
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 @@
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 3f7a7ae..b63c37f 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 @@
* 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 @@
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 @@
#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 @@
#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 @@
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 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 @@
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 985074c..740047d 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -39,11 +39,9 @@
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 eb12854..7d4c906 100644
--- a/src/runtime_support_asm.S
+++ b/src/runtime_support_asm.S
@@ -77,14 +77,6 @@
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 @@
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 87a2017..29531f4 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -59,6 +59,12 @@
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 @@
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 @@
pCheckSuspendFromCode = artCheckSuspendFromCode;
pFindNativeMethod = FindNativeMethod;
pDecodeJObjectInThread = DecodeJObjectInThread;
+ pResolveStringFromCode = ResolveStringFromCode;
pDebugMe = DebugMe;
}
diff --git a/src/thread.h b/src/thread.h
index c949339..e1939c8 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -232,12 +232,11 @@
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: