Visit libraries roots in JavaVMExt::VisitRoots

SharedLibrary holds a direct pointer to a class loader. Since class
loaders can move we need to visit these as roots and update them
during the GC. I believe this was causing UnsatisfiedLinkError with
background compaction enabled.

Bug: 8981901
Change-Id: I9e2a230c6dd3c25969abaf2121d8d473f6f8b601
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 80ca5fb..30b4ee8 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -523,6 +523,12 @@
     return dlsym(handle_, symbol_name.c_str());
   }
 
+  void VisitRoots(RootVisitor* visitor, void* arg) {
+    if (class_loader_ != nullptr) {
+      class_loader_ = visitor(class_loader_, arg);
+    }
+  }
+
  private:
   enum JNI_OnLoadState {
     kPending,
@@ -613,6 +619,12 @@
     return NULL;
   }
 
+  void VisitRoots(RootVisitor* visitor, void* arg) {
+    for (auto& lib_pair : libraries_) {
+      lib_pair.second->VisitRoots(visitor, arg);
+    }
+  }
+
  private:
   SafeMap<std::string, SharedLibrary*> libraries_;
 };
@@ -3385,6 +3397,11 @@
     MutexLock mu(self, pins_lock);
     pin_table.VisitRoots(visitor, arg);
   }
+  {
+    MutexLock mu(self, libraries_lock);
+    // Libraries contains shared libraries which hold a pointer to a class loader.
+    libraries->VisitRoots(visitor, arg);
+  }
   // The weak_globals table is visited by the GC itself (because it mutates the table).
 }