< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

Print this page

        

@@ -54,10 +54,11 @@
 #include "classfile/metadataOnStackMark.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/packageEntry.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
+#include "gc/shared/oopStorage.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"

@@ -508,10 +509,16 @@
 InstanceKlass* ClassLoaderDataGraph::try_get_next_class() {
   return static_klass_iterator.try_get_next_class();
 }
 
 
+void ClassLoaderData::update_holder(Handle holder) {
+  assert(holder() != NULL, "should be called with non-NULL loader");
+  assert(_holder.peek() == NULL, "never replace holders");
+  _holder = WeakHandle::create(holder);
+}
+
 // Remove a klass from the _klasses list for scratch_class during redefinition
 // or parsed class in the case of an error.
 void ClassLoaderData::remove_class(Klass* scratch_class) {
   assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
 

@@ -615,28 +622,18 @@
   // 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;
-    return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(o);
-  } else {
-    return NULL;
-  }
+  return _holder.resolve();
 }
 
 // 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();
-}
-
-bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const {
+bool ClassLoaderData::is_alive() const {
   bool alive = keep_alive() // null class loader and incomplete anonymous klasses.
-      || is_alive_closure->do_object_b(keep_alive_object());
+      || _holder.is_null()
+      || (_holder.peek() != NULL);  // not cleaned by weak reference processing
 
   return alive;
 }
 
 class ReleaseKlassClosure: public KlassClosure {

@@ -666,10 +663,15 @@
   classes_do(&cl);
 
   ClassLoaderDataGraph::dec_array_classes(cl.array_class_released());
   ClassLoaderDataGraph::dec_instance_classes(cl.instance_class_released());
 
+  // Release the WeakHandle, if already set
+  if (!_holder.is_null()) {
+    _holder.release();
+  }
+
   // Release C heap allocated hashtable for all the packages.
   if (_packages != NULL) {
     // Destroy the table itself
     delete _packages;
     _packages = NULL;

@@ -967,21 +969,25 @@
                                      // ClassLoaderData in the graph since the CLD
                                      // contains unhandled oops
 
   ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
 
-
   if (!is_anonymous) {
     // First, Atomically set it
     ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
     if (old != NULL) {
       delete cld;
       // Returns the data.
       return old;
     }
+
+    // Update the holder if we've won the race
+    // The holder of this class is the class_loader generically.
+    cld->update_holder(loader);
   }
 
+
   // We won the race, and therefore the task of adding the data to the list of
   // class loader data
   ClassLoaderData** list_head = &_head;
   ClassLoaderData* next = _head;
 

@@ -1242,10 +1248,12 @@
                                         bool clean_previous_versions) {
 
   ClassLoaderData* data = _head;
   ClassLoaderData* prev = NULL;
   bool seen_dead_loader = false;
+  int  loaders_processed = 0;
+  int  loaders_removed = 0;
 
   // Mark metadata seen on the stack only so we can delete unneeded entries.
   // Only walk all metadata, including the expensive code cache walk, for Full GC
   // and only if class redefinition and if there's previous versions of
   // Klasses to delete.

@@ -1258,21 +1266,23 @@
   // purging and we don't want to rewalk the previously unloaded class loader data.
   _saved_unloading = _unloading;
 
   data = _head;
   while (data != NULL) {
-    if (data->is_alive(is_alive_closure)) {
+    if (data->is_alive()) {
       // clean metaspace
       if (walk_all_metadata) {
         data->classes_do(InstanceKlass::purge_previous_versions);
       }
       data->free_deallocate_list();
       prev = data;
       data = data->next();
+      loaders_processed++;
       continue;
     }
     seen_dead_loader = true;
+    loaders_removed++;
     ClassLoaderData* dead = data;
     dead->unload();
     data = data->next();
     // Remove from loader list.
     // This class loader data will no longer be found

@@ -1311,10 +1321,12 @@
     }
 
     post_class_unload_events();
   }
 
+  log_debug(class, loader, data)("do_unloading: loaders processed %d, loaders removed %d", loaders_processed, loaders_removed);
+
   return seen_dead_loader;
 }
 
 void ClassLoaderDataGraph::purge() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
< prev index next >