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: