From 50ae95ff4a2002b49cab1a800f90dead4cc67620 Mon Sep 17 00:00:00 2001 From: mgronlun Date: Tue, 1 Jul 2014 10:36:19 +0200 Subject: [PATCH] 8047812: Ensure ClassLoaderDataGraph::classes_unloading_do only delivers klasses from CLDs with non-reclaimed class loader oops Reviewed-by: coleenp, sspitsyn, ehelin --- src/share/vm/classfile/classLoaderData.cpp | 10 +++++++++- src/share/vm/classfile/classLoaderData.hpp | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/share/vm/classfile/classLoaderData.cpp b/src/share/vm/classfile/classLoaderData.cpp index 033a8257d..2c613bd5b 100644 --- a/src/share/vm/classfile/classLoaderData.cpp +++ b/src/share/vm/classfile/classLoaderData.cpp @@ -531,6 +531,7 @@ bool ClassLoaderData::contains_klass(Klass* klass) { // GC root of class loader data created. ClassLoaderData* ClassLoaderDataGraph::_head = NULL; ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; +ClassLoaderData* ClassLoaderDataGraph::_saved_unloading = NULL; ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; bool ClassLoaderDataGraph::_should_purge = false; @@ -628,7 +629,9 @@ void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) { void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); - for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { + // Only walk the head until any clds not purged from prior unloading + // (CMS doesn't purge right away). + for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) { cld->classes_do(f); } } @@ -676,6 +679,11 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { ClassLoaderData* data = _head; ClassLoaderData* prev = NULL; bool seen_dead_loader = false; + + // 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; + // 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(); diff --git a/src/share/vm/classfile/classLoaderData.hpp b/src/share/vm/classfile/classLoaderData.hpp index adb8e95bd..bd8dcc0ab 100644 --- a/src/share/vm/classfile/classLoaderData.hpp +++ b/src/share/vm/classfile/classLoaderData.hpp @@ -66,6 +66,7 @@ class ClassLoaderDataGraph : public AllStatic { static ClassLoaderData* _unloading; // CMS support. static ClassLoaderData* _saved_head; + static ClassLoaderData* _saved_unloading; static bool _should_purge; static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS); -- GitLab