Enable class unloading

Also added class unloading test. Added a missing write barrier in
the class linker to fix a heap corruption error.

Bug: 22720414
Change-Id: Iff615d69b574a4438e91d4c844279d202f4f2736
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6b9c8aa..15f8f0b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1316,13 +1316,6 @@
     // 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(buffered_visitor);
-    // TODO: Avoid marking these to enable class unloading.
-    JavaVMExt* const vm = Runtime::Current()->GetJavaVM();
-    for (const ClassLoaderData& data : class_loaders_) {
-      mirror::Object* class_loader = vm->DecodeWeakGlobal(self, data.weak_root);
-      // Don't need to update anything since the class loaders will be updated by SweepSystemWeaks.
-      visitor->VisitRootIfNonNull(&class_loader, RootInfo(kRootVMInternal));
-    }
   } else if ((flags & kVisitRootFlagNewRoots) != 0) {
     for (auto& root : new_class_roots_) {
       mirror::Class* old_ref = root.Read<kWithoutReadBarrier>();
@@ -4266,6 +4259,11 @@
       ClassTable* const table = InsertClassTableForClassLoader(class_loader);
       mirror::Class* existing = table->UpdateClass(descriptor, h_new_class.Get(),
                                                    ComputeModifiedUtf8Hash(descriptor));
+      if (class_loader != nullptr) {
+        // We updated the class in the class table, perform the write barrier so that the GC knows
+        // about the change.
+        Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader);
+      }
       CHECK_EQ(existing, klass.Get());
       if (kIsDebugBuild && class_loader == nullptr && dex_cache_image_class_lookup_required_) {
         // Check a class loaded with the system class loader matches one in the image if the class