--- old/src/hotspot/share/classfile/systemDictionary.cpp 2018-10-29 23:13:08.990228334 -0400 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2018-10-29 23:13:08.758228323 -0400 @@ -1855,18 +1855,26 @@ bool do_cleaning) { bool unloading_occurred; + bool is_concurrent = SafepointSynchronize::is_at_safepoint(); { GCTraceTime(Debug, gc, phases) t("ClassLoaderData", gc_timer); - + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); // caller locks. // First, mark for unload all ClassLoaderData referencing a dead class loader. unloading_occurred = ClassLoaderDataGraph::do_unloading(do_cleaning); + if (unloading_occurred) { + MutexLockerEx ml2(is_concurrent ? Module_lock : NULL); JFR_ONLY(Jfr::on_unloading_classes();) + MutexLockerEx ml1(is_concurrent ? SystemDictionary_lock : NULL); ClassLoaderDataGraph::clean_module_and_package_info(); } } - // TODO: just return if !unloading_occurred. + if (do_cleaning) { + GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer); + ResolvedMethodTable::trigger_cleanup(); + } + if (unloading_occurred) { { GCTraceTime(Debug, gc, phases) t("SymbolTable", gc_timer); @@ -1875,23 +1883,21 @@ } { + MutexLockerEx ml(is_concurrent ? SystemDictionary_lock : NULL); GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer); constraints()->purge_loader_constraints(); resolution_errors()->purge_resolution_errors(); } - } - { - GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer); - // Oops referenced by the protection domain cache table may get unreachable independently - // of the class loader (eg. cached protection domain oops). So we need to - // explicitly unlink them here. - _pd_cache_table->trigger_cleanup(); - } - - if (do_cleaning) { - GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer); - ResolvedMethodTable::trigger_cleanup(); + { + GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer); + // Oops referenced by the protection domain cache table may get unreachable independently + // of the class loader (eg. cached protection domain oops). So we need to + // explicitly unlink them here. + // All protection domain oops are linked to the caller class, so if nothing + // unloads, this is not needed. + _pd_cache_table->trigger_cleanup(); + } } return unloading_occurred;