Visit class roots from ClassLoader::VisitReferences

This causes the classes of a class loader to get marked when that
class loader gets marked instead of during class root visiting.

Bug: 22720414

Change-Id: If53f042aff1d9f7bf94ecbe6886601edda029b7d
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0886e32..f19263d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -37,6 +37,7 @@
 #include "base/unix_file/fd_file.h"
 #include "base/value_object.h"
 #include "class_linker-inl.h"
+#include "class_table-inl.h"
 #include "compiler_callbacks.h"
 #include "debugger.h"
 #include "dex_file-inl.h"
@@ -582,6 +583,7 @@
 
   // Setup the ClassLoader, verifying the object_size_.
   class_root = FindSystemClass(self, "Ljava/lang/ClassLoader;");
+  class_root->SetClassLoaderClass();
   CHECK_EQ(class_root->GetObjectSize(), mirror::ClassLoader::InstanceSize());
   SetClassRoot(kJavaLangClassLoader, class_root);
 
@@ -1273,15 +1275,10 @@
     // Moving concurrent:
     // Need to make sure to not copy ArtMethods without doing read barriers since the roots are
     // marked concurrently and we don't hold the classlinker_classes_lock_ when we do the copy.
-    boot_class_table_.VisitRoots(visitor, flags);
+    boot_class_table_.VisitRoots(buffered_visitor);
     for (GcRoot<mirror::ClassLoader>& root : class_loaders_) {
       // May be null for boot ClassLoader.
       root.VisitRoot(visitor, RootInfo(kRootVMInternal));
-      ClassTable* const class_table = root.Read()->GetClassTable();
-      if (class_table != nullptr) {
-        // May be null if we have no classes.
-        class_table->VisitRoots(visitor, flags);
-      }
     }
   } else if ((flags & kVisitRootFlagNewRoots) != 0) {
     for (auto& root : new_class_roots_) {
@@ -2810,6 +2807,10 @@
   }
   VerifyObject(klass);
   class_table->InsertWithHash(klass, hash);
+  if (class_loader != nullptr) {
+    // This is necessary because we need to have the card dirtied for remembered sets.
+    Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader);
+  }
   if (log_new_class_table_roots_) {
     new_class_roots_.push_back(GcRoot<mirror::Class>(klass));
   }
@@ -4375,6 +4376,11 @@
     klass->SetFinalizable();
   }
 
+  // Inherit class loader flag form super class.
+  if (super->IsClassLoaderClass()) {
+    klass->SetClassLoaderClass();
+  }
+
   // Inherit reference flags (if any) from the superclass.
   int reference_flags = (super->GetAccessFlags() & kAccReferenceFlagsMask);
   if (reference_flags != 0) {