Don't unload shared libraries for null class loader.
If we load a shared library in the boot class loader (null),
then we create the SharedLibrary with a null class loader. We
shouldn't unload this shared library if the class loader decodes to
null since it may still be in use.
Fixes some hangs in gcstress tests.
Bug: 22720414
Change-Id: I52eca4cdba2c5ddd8e3dc7d133d253e5626c5b44
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index ab70d02..b5e28e9 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -265,7 +265,11 @@
for (auto it = libraries_.begin(); it != libraries_.end(); ) {
SharedLibrary* const library = it->second;
// If class loader is null then it was unloaded, call JNI_OnUnload.
- if (soa.Decode<mirror::ClassLoader*>(library->GetClassLoader()) == nullptr) {
+ const jweak class_loader = library->GetClassLoader();
+ // If class_loader is a null jobject then it is the boot class loader. We should not unload
+ // the native libraries of the boot class loader.
+ if (class_loader != nullptr &&
+ soa.Decode<mirror::ClassLoader*>(class_loader) == nullptr) {
void* const sym = library->FindSymbol("JNI_OnUnload", nullptr);
if (sym == nullptr) {
VLOG(jni) << "[No JNI_OnUnload found in \"" << library->GetPath() << "\"]";