--- old/src/hotspot/share/classfile/classLoaderData.cpp 2018-03-19 19:09:47.736507868 -0400 +++ new/src/hotspot/share/classfile/classLoaderData.cpp 2018-03-19 19:09:47.129452085 -0400 @@ -610,6 +610,19 @@ return new Dictionary(this, size, resizable); } +// Tell the GC to keep this klass alive while iterating ClassLoaderDataGraph +void ClassLoaderData::ensure_loader_alive() { + // A klass that was previously considered dead can be looked up in the + // CLD/SD, and its _java_mirror or _class_loader can be stored in a root + // or a reachable object making it alive again. The SATB part of G1 needs + // to get notified about this potential resurrection, otherwise the marking + // might not find the object. + if (!keep_alive()) { + oop* o = is_anonymous() ? _klasses->java_mirror_handle().ptr_raw() : &_class_loader; + (void)RootAccess::oop_load(o); + } +} + // Unloading support oop ClassLoaderData::keep_alive_object() const { assert_locked_or_safepoint(_metaspace_lock); @@ -1049,18 +1062,21 @@ void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { + cld->ensure_loader_alive(); cld->classes_do(klass_closure); } } void ClassLoaderDataGraph::classes_do(void f(Klass* const)) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { + cld->ensure_loader_alive(); cld->classes_do(f); } } void ClassLoaderDataGraph::methods_do(void f(Method*)) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { + cld->ensure_loader_alive(); cld->methods_do(f); } } @@ -1068,6 +1084,7 @@ void ClassLoaderDataGraph::modules_do(void f(ModuleEntry*)) { assert_locked_or_safepoint(Module_lock); for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { + cld->ensure_loader_alive(); cld->modules_do(f); } } @@ -1085,6 +1102,7 @@ void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) { assert_locked_or_safepoint(Module_lock); for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { + cld->ensure_loader_alive(); cld->packages_do(f); } } @@ -1101,6 +1119,7 @@ void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { + cld->ensure_loader_alive(); cld->loaded_classes_do(klass_closure); } } @@ -1122,6 +1141,7 @@ // Only walks the classes defined in this class loader. void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*)) { FOR_ALL_DICTIONARY(cld) { + cld->ensure_loader_alive(); cld->dictionary()->classes_do(f); } } @@ -1129,6 +1149,7 @@ // Only walks the classes defined in this class loader. void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*, TRAPS), TRAPS) { FOR_ALL_DICTIONARY(cld) { + cld->ensure_loader_alive(); cld->dictionary()->classes_do(f, CHECK); } } @@ -1136,6 +1157,7 @@ // Walks all entries in the dictionary including entries initiated by this class loader. void ClassLoaderDataGraph::dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) { FOR_ALL_DICTIONARY(cld) { + cld->ensure_loader_alive(); cld->dictionary()->all_entries_do(f); } }