< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

Print this page

        

@@ -594,10 +594,23 @@
     resizable = false;
   }
   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<ON_PHANTOM_OOP_REF>::oop_load(o);
+  }
+}
+
 // Unloading support
 oop ClassLoaderData::keep_alive_object() const {
   assert_locked_or_safepoint(_metaspace_lock);
   assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");
   return is_anonymous() ? _klasses->java_mirror() : class_loader();

@@ -1033,29 +1046,33 @@
   }
 }
 
 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);
   }
 }
 
 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);
   }
 }
 
 void ClassLoaderDataGraph::modules_unloading_do(void f(ModuleEntry*)) {

@@ -1069,10 +1086,11 @@
 }
 
 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);
   }
 }
 
 void ClassLoaderDataGraph::packages_unloading_do(void f(PackageEntry*)) {

@@ -1085,10 +1103,11 @@
   }
 }
 
 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);
   }
 }
 
 void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {

@@ -1106,30 +1125,34 @@
 
 // Walk classes in the loaded class dictionaries in various forms.
 // 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);
   }
 }
 
 // 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);
   }
 }
 
 // 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);
   }
 }
 
 void ClassLoaderDataGraph::verify_dictionary() {
   FOR_ALL_DICTIONARY(cld) {
+    cld->ensure_loader_alive();
     cld->dictionary()->verify();
   }
 }
 
 void ClassLoaderDataGraph::print_dictionary(outputStream* st) {
< prev index next >