hotspot/src/share/vm/classfile/classLoaderData.cpp
changeset 29576 c223b0a9872e
parent 29081 c61eb4914428
child 29577 bb06d25e302d
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Tue Mar 10 19:56:19 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri Mar 13 12:40:39 2015 -0400
@@ -467,6 +467,12 @@
       } else {
         ShouldNotReachHere();
       }
+    } else {
+      // Metadata is alive.
+      // If scratch_class is on stack then it shouldn't be on this list!
+      assert(!m->is_klass() || !((InstanceKlass*)m)->is_scratch_class(),
+             "scratch classes on this list should be dead");
+      // Also should assert that other metadata on the list was found in handles.
     }
   }
 }
@@ -737,11 +743,22 @@
 
 // Move class loader data from main list to the unloaded list for unloading
 // and deallocation later.
-bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure, bool clean_alive) {
+bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure,
+                                        bool clean_previous_versions) {
+
   ClassLoaderData* data = _head;
   ClassLoaderData* prev = NULL;
   bool seen_dead_loader = false;
 
+  // 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.
+  bool walk_all_metadata = clean_previous_versions &&
+                           JvmtiExport::has_redefined_a_class() &&
+                           InstanceKlass::has_previous_versions();
+  MetadataOnStackMark md_on_stack(walk_all_metadata);
+
   // Save previous _unloading pointer for CMS which may add to unloading list before
   // purging and we don't want to rewalk the previously unloaded class loader data.
   _saved_unloading = _unloading;
@@ -749,6 +766,11 @@
   data = _head;
   while (data != NULL) {
     if (data->is_alive(is_alive_closure)) {
+      // clean metaspace
+      if (walk_all_metadata) {
+        data->classes_do(InstanceKlass::purge_previous_versions);
+      }
+      data->free_deallocate_list();
       prev = data;
       data = data->next();
       continue;
@@ -770,11 +792,6 @@
     _unloading = dead;
   }
 
-  if (clean_alive) {
-    // Clean previous versions and the deallocate list.
-    ClassLoaderDataGraph::clean_metaspaces();
-  }
-
   if (seen_dead_loader) {
     post_class_unload_events();
   }
@@ -782,21 +799,6 @@
   return seen_dead_loader;
 }
 
-void ClassLoaderDataGraph::clean_metaspaces() {
-  // mark metadata seen on the stack and code cache so we can delete unneeded entries.
-  bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
-  MetadataOnStackMark md_on_stack(has_redefined_a_class);
-
-  if (has_redefined_a_class) {
-    for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
-      data->classes_do(InstanceKlass::purge_previous_versions);
-    }
-  }
-
-  // Should purge the previous version before deallocating.
-  free_deallocate_lists();
-}
-
 void ClassLoaderDataGraph::purge() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
   ClassLoaderData* list = _unloading;
@@ -829,12 +831,6 @@
 #endif
 }
 
-void ClassLoaderDataGraph::free_deallocate_lists() {
-  for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
-    cld->free_deallocate_list();
-  }
-}
-
 // CDS support
 
 // Global metaspaces for writing information to the shared archive.  When