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).
}