From 46e857a8b905a59254ca749f664d1e808918f558 Mon Sep 17 00:00:00 2001 From: Sebastien Hertz Date: Thu, 6 Aug 2015 12:52:43 +0200 Subject: [PATCH] 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 --- runtime/class_linker.cc | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 62ba907e2..a306c3025 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1097,6 +1097,28 @@ static void SanityCheckObjectsCallback(mirror::Object* obj, void* arg ATTRIBUTE_ } } +// 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 @@ void ClassLinker::InitFromImage() { // 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(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_ -- 2.11.0