Additional debug logging for bug 33231647.

Bug: 33231647
Test: m test-art-host
Change-Id: I5847ce92be5f588852e04ff44fe6eca19f363b93
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 4407968..6aa5642 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -864,6 +864,7 @@
       const char* descriptor = klass->GetDescriptor(&storage);
       bool result = class_table->Remove(descriptor);
       DCHECK(result);
+      DCHECK(!class_table->Remove(descriptor)) << descriptor;
     }
     return defined_class_count_;
   }
@@ -898,6 +899,12 @@
   size_t removed_class_count_;
 };
 
+void ImageWriter::VisitClassLoaders(ClassLoaderVisitor* visitor) {
+  ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  visitor->Visit(nullptr);  // Visit boot class loader.
+  Runtime::Current()->GetClassLinker()->VisitClassLoaders(visitor);
+}
+
 void ImageWriter::PruneNonImageClasses() {
   Runtime* runtime = Runtime::Current();
   ClassLinker* class_linker = runtime->GetClassLinker();
@@ -909,10 +916,8 @@
 
   // Remove the undesired classes from the class roots.
   {
-    ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_);
     PruneClassLoaderClassesVisitor class_loader_visitor(this);
-    class_loader_visitor.Visit(nullptr);  // Visit boot class loader.
-    class_linker->VisitClassLoaders(&class_loader_visitor);
+    VisitClassLoaders(&class_loader_visitor);
     VLOG(compiler) << "Pruned " << class_loader_visitor.GetRemovedClassCount() << " classes";
   }
 
@@ -1170,12 +1175,41 @@
               return it->second ? "true" : "false";
             }
           }
+          std::string ClassLoaders(ImageWriter* writer, mirror::Class* klass) const
+              REQUIRES_SHARED(Locks::mutator_lock_) {
+            struct DumpVisitor : ClassLoaderVisitor {
+              explicit DumpVisitor(mirror::Class* the_klass)
+                  : klass_(the_klass),
+                    storage_(),
+                    descriptor_(the_klass->GetDescriptor(&storage_)) { }
+              void Visit(ObjPtr<mirror::ClassLoader> class_loader) OVERRIDE
+                    REQUIRES_SHARED(Locks::classlinker_classes_lock_, Locks::mutator_lock_) {
+                ClassTable* class_table =
+                    Runtime::Current()->GetClassLinker()->ClassTableForClassLoader(class_loader);
+                if (class_table->Contains(klass_)) {
+                  result_ << ";" << static_cast<const void*>(class_loader.Ptr()) << "/"
+                      << (class_loader == klass_->GetClassLoader() ? "defining" : "initiating")
+                      << "/"
+                      << (class_table->LookupByDescriptor(klass_) == klass_ ? "ok" : "mismatch");
+                }
+              }
+              mirror::Class* klass_;
+              std::string storage_;
+              const char* descriptor_;
+              std::ostringstream result_;
+            };
+            DumpVisitor visitor(klass);
+            writer->VisitClassLoaders(&visitor);
+            std::string result = visitor.result_.str();
+            return result.empty() ? "<none>" : /* drop leading ';' */ result.substr(1u);
+          }
         };
         CHECK(!IsBootClassLoaderClass(as_klass)) << as_klass->PrettyClass()
             << " status:" << as_klass->GetStatus()
             << " " << static_cast<const void*>(as_klass)
             << " " << Dumper().ImageRanges()
-            << " prune_memo:" << Dumper().PruneMemo(this, as_klass, prune_class_memo_);
+            << " prune_memo:" << Dumper().PruneMemo(this, as_klass, prune_class_memo_)
+            << " loaders:" << Dumper().ClassLoaders(this, as_klass);
       }
       LengthPrefixedArray<ArtField>* fields[] = {
           as_klass->GetSFieldsPtr(), as_klass->GetIFieldsPtr(),
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index ad6ffd8..c537483 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -50,6 +50,7 @@
 }  // namespace space
 }  // namespace gc
 
+class ClassLoaderVisitor;
 class ClassTable;
 
 static constexpr int kInvalidFd = -1;
@@ -373,6 +374,9 @@
   void ComputeLazyFieldsForImageClasses()
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Visit all class loaders.
+  void VisitClassLoaders(ClassLoaderVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
+
   // Remove unwanted classes from various roots.
   void PruneNonImageClasses() REQUIRES_SHARED(Locks::mutator_lock_);