--- old/src/share/vm/classfile/classLoaderData.cpp 2019-02-15 19:02:22.239364494 +0300 +++ new/src/share/vm/classfile/classLoaderData.cpp 2019-02-15 19:02:22.131368274 +0300 @@ -64,8 +64,10 @@ #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" -#if INCLUDE_TRACE -#include "trace/tracing.hpp" +#include "utilities/ticks.hpp" +#if INCLUDE_JFR +#include "jfr/jfr.hpp" +#include "jfr/jfrEvents.hpp" #endif ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; @@ -81,7 +83,8 @@ _claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), _next(NULL), _dependencies(dependencies), _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { - // empty + + JFR_ONLY(INIT_ID(this);) } void ClassLoaderData::init_dependencies(TRAPS) { @@ -646,6 +649,16 @@ } } +void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); + // 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()) { + assert(cld->is_unloading(), "invariant"); + cl->do_cld(cld); + } +} + void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->_next) { CLDClosure* closure = cld->keep_alive() ? strong : weak; @@ -740,6 +753,28 @@ } #endif // PRODUCT +#if INCLUDE_JFR +static Ticks class_unload_time; +static void post_class_unload_event(Klass* const k) { + assert(k != NULL, "invariant"); + EventClassUnload event(UNTIMED); + event.set_endtime(class_unload_time); + event.set_unloadedClass(k); + event.set_definingClassLoader(k->class_loader_data()); + event.commit(); +} + +static void post_class_unload_events() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); + if (Jfr::is_enabled()) { + if (EventClassUnload::is_enabled()) { + class_unload_time = Ticks::now(); + ClassLoaderDataGraph::classes_unloading_do(&post_class_unload_event); + } + Jfr::on_unloading_classes(); + } +} +#endif // INCLUDE_JFR // Move class loader data from main list to the unloaded list for unloading // and deallocation later. @@ -781,7 +816,7 @@ } if (seen_dead_loader) { - post_class_unload_events(); + JFR_ONLY(post_class_unload_events();) } return seen_dead_loader; @@ -820,20 +855,6 @@ Metaspace::purge(); } -void ClassLoaderDataGraph::post_class_unload_events(void) { -#if INCLUDE_TRACE - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); - if (Tracing::enabled()) { - if (Tracing::is_event_enabled(TraceClassUnloadEvent)) { - assert(_unloading != NULL, "need class loader data unload list!"); - _class_unload_time = Ticks::now(); - classes_unloading_do(&class_unload_event); - } - Tracing::on_unloading_classes(); - } -#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 @@ -969,21 +990,3 @@ class_loader()->print_value_on(out); } } - -#if INCLUDE_TRACE - -Ticks ClassLoaderDataGraph::_class_unload_time; - -void ClassLoaderDataGraph::class_unload_event(Klass* const k) { - - // post class unload event - EventClassUnload event(UNTIMED); - event.set_endtime(_class_unload_time); - event.set_unloadedClass(k); - oop defining_class_loader = k->class_loader(); - event.set_definingClassLoader(defining_class_loader != NULL ? - defining_class_loader->klass() : (Klass*)NULL); - event.commit(); -} - -#endif // INCLUDE_TRACE