Fix image loading in interpeter-only mode

Follow-up https://android-review.googlesource.com/162935. We now need
an ArtMethodVisitor to update entrypoints of methods in the image.

Bug: 22832610
Change-Id: I30ca9c369a73c3372694b446e73afa2e37890a65
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 62ba907..a306c30 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1097,6 +1097,28 @@
   }
 }
 
+// Set image methods' entry point to interpreter.
+class SetInterpreterEntrypointArtMethodVisitor : public ArtMethodVisitor {
+ public:
+  explicit SetInterpreterEntrypointArtMethodVisitor(size_t image_pointer_size)
+    : image_pointer_size_(image_pointer_size) {}
+
+  void Visit(ArtMethod* method) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
+    if (kIsDebugBuild && !method->IsRuntimeMethod()) {
+      CHECK(method->GetDeclaringClass() != nullptr);
+    }
+    if (!method->IsNative() && !method->IsRuntimeMethod() && !method->IsResolutionMethod()) {
+      method->SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(),
+                                                        image_pointer_size_);
+    }
+  }
+
+ private:
+  const size_t image_pointer_size_;
+
+  DISALLOW_COPY_AND_ASSIGN(SetInterpreterEntrypointArtMethodVisitor);
+};
+
 void ClassLinker::InitFromImage() {
   VLOG(startup) << "ClassLinker::InitFromImage entering";
   CHECK(!init_done_);
@@ -1187,19 +1209,11 @@
 
   // Set entry point to interpreter if in InterpretOnly mode.
   if (!runtime->IsAotCompiler() && runtime->GetInstrumentation()->InterpretOnly()) {
-    const auto& header = space->GetImageHeader();
-    const auto& methods = header.GetMethodsSection();
-    const auto art_method_size = ArtMethod::ObjectSize(image_pointer_size_);
-    for (uintptr_t pos = 0; pos < methods.Size(); pos += art_method_size) {
-      auto* method = reinterpret_cast<ArtMethod*>(space->Begin() + pos + methods.Offset());
-      if (kIsDebugBuild && !method->IsRuntimeMethod()) {
-        CHECK(method->GetDeclaringClass() != nullptr);
-      }
-      if (!method->IsNative() && !method->IsRuntimeMethod() && !method->IsResolutionMethod()) {
-        method->SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(),
-                                                          image_pointer_size_);
-      }
-    }
+    const ImageHeader& header = space->GetImageHeader();
+    const ImageSection& methods = header.GetMethodsSection();
+    const size_t art_method_size = ArtMethod::ObjectSize(image_pointer_size_);
+    SetInterpreterEntrypointArtMethodVisitor visitor(image_pointer_size_);
+    methods.VisitPackedArtMethods(&visitor, space->Begin(), art_method_size);
   }
 
   // reinit class_roots_