--- 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