diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 2a9c0d4..26ab602 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -19,6 +19,7 @@
 #include <cmath>
 
 #include "mirror/array-inl.h"
+#include "unstarted_runtime.h"
 
 namespace art {
 namespace interpreter {
@@ -450,10 +451,6 @@
   UNREACHABLE();
 }
 
-static void UnstartedRuntimeInvoke(Thread* self, const DexFile::CodeItem* code_item,
-                                   ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
 // Assign register 'src_reg' from shadow_frame to register 'dest_reg' into new_shadow_frame.
 static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFrame& shadow_frame,
                                   size_t dest_reg, size_t src_reg)
@@ -733,279 +730,6 @@
   }
 }
 
-// Helper function to deal with class loading in an unstarted runtime.
-static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
-                                      Handle<mirror::ClassLoader> class_loader, JValue* result,
-                                      const std::string& method_name, bool initialize_class,
-                                      bool abort_if_not_found)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  CHECK(className.Get() != nullptr);
-  std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-
-  Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
-  if (found == nullptr && abort_if_not_found) {
-    if (!self->IsExceptionPending()) {
-      AbortTransaction(self, "%s failed in un-started runtime for class: %s",
-                       method_name.c_str(), PrettyDescriptor(descriptor.c_str()).c_str());
-    }
-    return;
-  }
-  if (found != nullptr && initialize_class) {
-    StackHandleScope<1> hs(self);
-    Handle<mirror::Class> h_class(hs.NewHandle(found));
-    if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
-      CHECK(self->IsExceptionPending());
-      return;
-    }
-  }
-  result->SetL(found);
-}
-
-// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
-// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
-// ClassNotFoundException), so need to do the same. The only exception is if the exception is
-// actually InternalError. This must not be wrapped, as it signals an initialization abort.
-static void CheckExceptionGenerateClassNotFound(Thread* self)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  if (self->IsExceptionPending()) {
-    // If it is not an InternalError, wrap it.
-    std::string type(PrettyTypeOf(self->GetException()));
-    if (type != "java.lang.InternalError") {
-      self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
-                                     "ClassNotFoundException");
-    }
-  }
-}
-
-static void UnstartedRuntimeInvoke(Thread* self,  const DexFile::CodeItem* code_item,
-                                   ShadowFrame* shadow_frame,
-                                   JValue* result, size_t arg_offset) {
-  // In a runtime that's not started we intercept certain methods to avoid complicated dependency
-  // problems in core libraries.
-  std::string name(PrettyMethod(shadow_frame->GetMethod()));
-  if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") {
-    mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
-    StackHandleScope<1> hs(self);
-    Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
-    UnstartedRuntimeFindClass(self, h_class_name, NullHandle<mirror::ClassLoader>(), result, name,
-                              true, false);
-    CheckExceptionGenerateClassNotFound(self);
-  } else if (name == "java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader)") {
-    mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
-    bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
-    mirror::ClassLoader* class_loader =
-        down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
-    StackHandleScope<2> hs(self);
-    Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
-    Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
-    UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, name, initialize_class,
-                              false);
-    CheckExceptionGenerateClassNotFound(self);
-  } else if (name == "java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader)") {
-    mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
-    bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
-    mirror::ClassLoader* class_loader =
-        down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
-    StackHandleScope<2> hs(self);
-    Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
-    Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
-    UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, name, initialize_class,
-                              false);
-    CheckExceptionGenerateClassNotFound(self);
-  } else if (name == "java.lang.Class java.lang.VMClassLoader.findLoadedClass(java.lang.ClassLoader, java.lang.String)") {
-    mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
-    mirror::ClassLoader* class_loader =
-        down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
-    StackHandleScope<2> hs(self);
-    Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
-    Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
-    UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, name, false, false);
-    // This might have an error pending. But semantics are to just return null.
-    if (self->IsExceptionPending()) {
-      // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
-      std::string type(PrettyTypeOf(self->GetException()));
-      if (type != "java.lang.InternalError") {
-        self->ClearException();
-      }
-    }
-  } else if (name == "java.lang.Class java.lang.Void.lookupType()") {
-    result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
-  } else if (name == "java.lang.Object java.lang.Class.newInstance()") {
-    StackHandleScope<3> hs(self);  // Class, constructor, object.
-    Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
-    Handle<Class> h_klass(hs.NewHandle(klass));
-    // There are two situations in which we'll abort this run.
-    //  1) If the class isn't yet initialized and initialization fails.
-    //  2) If we can't find the default constructor. We'll postpone the exception to runtime.
-    // Note that 2) could likely be handled here, but for safety abort the transaction.
-    bool ok = false;
-    if (Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
-      Handle<ArtMethod> h_cons(hs.NewHandle(h_klass->FindDeclaredDirectMethod("<init>", "()V")));
-      if (h_cons.Get() != nullptr) {
-        Handle<Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
-        CHECK(h_obj.Get() != nullptr);  // We don't expect OOM at compile-time.
-        EnterInterpreterFromInvoke(self, h_cons.Get(), h_obj.Get(), nullptr, nullptr);
-        if (!self->IsExceptionPending()) {
-          result->SetL(h_obj.Get());
-          ok = true;
-        }
-      } else {
-        self->ThrowNewExceptionF("Ljava/lang/InternalError;",
-                                 "Could not find default constructor for '%s'",
-                                 PrettyClass(h_klass.Get()).c_str());
-      }
-    }
-    if (!ok) {
-      std::string error_msg = StringPrintf("Failed in Class.newInstance for '%s' with %s",
-                                           PrettyClass(h_klass.Get()).c_str(),
-                                           PrettyTypeOf(self->GetException()).c_str());
-      self->ThrowNewWrappedException("Ljava/lang/InternalError;", error_msg.c_str());
-    }
-  } else if (name == "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") {
-    // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
-    // going the reflective Dex way.
-    Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
-    String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
-    ArtField* found = NULL;
-    ObjectArray<ArtField>* fields = klass->GetIFields();
-    for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) {
-      ArtField* f = fields->Get(i);
-      if (name2->Equals(f->GetName())) {
-        found = f;
-      }
-    }
-    if (found == NULL) {
-      fields = klass->GetSFields();
-      for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) {
-        ArtField* f = fields->Get(i);
-        if (name2->Equals(f->GetName())) {
-          found = f;
-        }
-      }
-    }
-    CHECK(found != NULL)
-        << "Failed to find field in Class.getDeclaredField in un-started runtime. name="
-        << name2->ToModifiedUtf8() << " class=" << PrettyDescriptor(klass);
-    // TODO: getDeclaredField calls GetType once the field is found to ensure a
-    //       NoClassDefFoundError is thrown if the field's type cannot be resolved.
-    Class* jlr_Field = self->DecodeJObject(WellKnownClasses::java_lang_reflect_Field)->AsClass();
-    StackHandleScope<1> hs(self);
-    Handle<Object> field(hs.NewHandle(jlr_Field->AllocNonMovableObject(self)));
-    CHECK(field.Get() != NULL);
-    ArtMethod* c = jlr_Field->FindDeclaredDirectMethod("<init>", "(Ljava/lang/reflect/ArtField;)V");
-    uint32_t args[1];
-    args[0] = StackReference<mirror::Object>::FromMirrorPtr(found).AsVRegValue();
-    EnterInterpreterFromInvoke(self, c, field.Get(), args, NULL);
-    result->SetL(field.Get());
-  } else if (name == "int java.lang.Object.hashCode()") {
-    Object* obj = shadow_frame->GetVRegReference(arg_offset);
-    result->SetI(obj->IdentityHashCode());
-  } else if (name == "java.lang.String java.lang.reflect.ArtMethod.getMethodName(java.lang.reflect.ArtMethod)") {
-    mirror::ArtMethod* method = shadow_frame->GetVRegReference(arg_offset)->AsArtMethod();
-    result->SetL(method->GetNameAsString(self));
-  } else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)" ||
-             name == "void java.lang.System.arraycopy(char[], int, char[], int, int)" ||
-             name == "void java.lang.System.arraycopy(int[], int, int[], int, int)") {
-    // Special case array copying without initializing System.
-    Class* ctype = shadow_frame->GetVRegReference(arg_offset)->GetClass()->GetComponentType();
-    jint srcPos = shadow_frame->GetVReg(arg_offset + 1);
-    jint dstPos = shadow_frame->GetVReg(arg_offset + 3);
-    jint length = shadow_frame->GetVReg(arg_offset + 4);
-    if (!ctype->IsPrimitive()) {
-      ObjectArray<Object>* src = shadow_frame->GetVRegReference(arg_offset)->AsObjectArray<Object>();
-      ObjectArray<Object>* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<Object>();
-      for (jint i = 0; i < length; ++i) {
-        dst->Set(dstPos + i, src->Get(srcPos + i));
-      }
-    } else if (ctype->IsPrimitiveChar()) {
-      CharArray* src = shadow_frame->GetVRegReference(arg_offset)->AsCharArray();
-      CharArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray();
-      for (jint i = 0; i < length; ++i) {
-        dst->Set(dstPos + i, src->Get(srcPos + i));
-      }
-    } else if (ctype->IsPrimitiveInt()) {
-      IntArray* src = shadow_frame->GetVRegReference(arg_offset)->AsIntArray();
-      IntArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsIntArray();
-      for (jint i = 0; i < length; ++i) {
-        dst->Set(dstPos + i, src->Get(srcPos + i));
-      }
-    } else {
-      self->ThrowNewExceptionF("Ljava/lang/InternalError;",
-                               "Unimplemented System.arraycopy for type '%s'",
-                               PrettyDescriptor(ctype).c_str());
-    }
-  } else if (name == "long java.lang.Double.doubleToRawLongBits(double)") {
-    double in = shadow_frame->GetVRegDouble(arg_offset);
-    result->SetJ(bit_cast<int64_t>(in));
-  } else if (name == "double java.lang.Math.ceil(double)") {
-    double in = shadow_frame->GetVRegDouble(arg_offset);
-    double out;
-    // Special cases:
-    // 1) NaN, infinity, +0, -0 -> out := in. All are guaranteed by cmath.
-    // -1 < in < 0 -> out := -0.
-    if (-1.0 < in && in < 0) {
-      out = -0.0;
-    } else {
-      out = ceil(in);
-    }
-    result->SetD(out);
-  } else if (name == "java.lang.Object java.lang.ThreadLocal.get()") {
-    std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
-    bool ok = false;
-    if (caller == "java.lang.String java.lang.IntegralToString.convertInt(java.lang.AbstractStringBuilder, int)") {
-      // Allocate non-threadlocal buffer.
-      result->SetL(mirror::CharArray::Alloc(self, 11));
-      ok = true;
-    } else if (caller == "java.lang.RealToString java.lang.RealToString.getInstance()") {
-      // Note: RealToString is implemented and used in a different fashion than IntegralToString.
-      // Conversion is done over an actual object of RealToString (the conversion method is an
-      // instance method). This means it is not as clear whether it is correct to return a new
-      // object each time. The caller needs to be inspected by hand to see whether it (incorrectly)
-      // stores the object for later use.
-      // See also b/19548084 for a possible rewrite and bringing it in line with IntegralToString.
-      if (shadow_frame->GetLink()->GetLink() != nullptr) {
-        std::string caller2(PrettyMethod(shadow_frame->GetLink()->GetLink()->GetMethod()));
-        if (caller2 == "java.lang.String java.lang.Double.toString(double)") {
-          // Allocate new object.
-          StackHandleScope<2> hs(self);
-          Handle<Class> h_real_to_string_class(hs.NewHandle(
-              shadow_frame->GetLink()->GetMethod()->GetDeclaringClass()));
-          Handle<Object> h_real_to_string_obj(hs.NewHandle(
-              h_real_to_string_class->AllocObject(self)));
-          if (h_real_to_string_obj.Get() != nullptr) {
-            mirror::ArtMethod* init_method =
-                h_real_to_string_class->FindDirectMethod("<init>", "()V");
-            if (init_method == nullptr) {
-              h_real_to_string_class->DumpClass(LOG(FATAL), mirror::Class::kDumpClassFullDetail);
-            } else {
-              JValue invoke_result;
-              EnterInterpreterFromInvoke(self, init_method, h_real_to_string_obj.Get(), nullptr,
-                                         nullptr);
-              if (!self->IsExceptionPending()) {
-                result->SetL(h_real_to_string_obj.Get());
-                ok = true;
-              }
-            }
-          }
-
-          if (!ok) {
-            // We'll abort, so clear exception.
-            self->ClearException();
-          }
-        }
-      }
-    }
-
-    if (!ok) {
-      self->ThrowNewException("Ljava/lang/InternalError;", "Unimplemented ThreadLocal.get");
-    }
-  } else {
-    // Not special, continue with regular interpreter execution.
-    artInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
-  }
-}
-
 // Explicit DoCall template function declarations.
 #define EXPLICIT_DO_CALL_TEMPLATE_DECL(_is_range, _do_assignability_check)                      \
   template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)                                          \
