--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Tue Oct 14 20:35:45 2014 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Oct 02 10:55:36 2014 +0200
@@ -734,7 +734,7 @@
// 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 ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure, bool clean_alive) {
ClassLoaderData* data = _head;
ClassLoaderData* prev = NULL;
bool seen_dead_loader = false;
@@ -743,27 +743,9 @@
// purging and we don't want to rewalk the previously unloaded class loader data.
_saved_unloading = _unloading;
- // 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) {
- // purge_previous_versions also cleans weak method links. Because
- // one method's MDO can reference another method from another
- // class loader, we need to first clean weak method links for all
- // class loaders here. Below, we can then free redefined methods
- // for all class loaders.
- while (data != NULL) {
- if (data->is_alive(is_alive_closure)) {
- data->classes_do(InstanceKlass::purge_previous_versions);
- }
- data = data->next();
- }
- }
data = _head;
while (data != NULL) {
if (data->is_alive(is_alive_closure)) {
- data->free_deallocate_list();
prev = data;
data = data->next();
continue;
@@ -785,6 +767,11 @@
_unloading = dead;
}
+ if (clean_alive) {
+ // Clean previous versions and the deallocate list.
+ ClassLoaderDataGraph::clean_metaspaces();
+ }
+
if (seen_dead_loader) {
post_class_unload_events();
}
@@ -792,6 +779,26 @@
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) {
+ // purge_previous_versions also cleans weak method links. Because
+ // one method's MDO can reference another method from another
+ // class loader, we need to first clean weak method links for all
+ // class loaders here. Below, we can then free redefined methods
+ // for all class loaders.
+ for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
+ data->classes_do(InstanceKlass::purge_previous_versions);
+ }
+ }
+
+ // Need to purge the previous version before deallocating.
+ free_deallocate_lists();
+}
+
void ClassLoaderDataGraph::purge() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
ClassLoaderData* list = _unloading;
@@ -819,6 +826,14 @@
#endif
}
+void ClassLoaderDataGraph::free_deallocate_lists() {
+ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ // We need to keep this data until InstanceKlass::purge_previous_version has been
+ // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces.
+ cld->free_deallocate_list();
+ }
+}
+
// CDS support
// Global metaspaces for writing information to the shared archive. When