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_