--- old/src/hotspot/share/classfile/classLoaderData.cpp 2018-08-23 18:48:18.121025125 -0400 +++ new/src/hotspot/share/classfile/classLoaderData.cpp 2018-08-23 18:48:17.684725156 -0400 @@ -76,11 +76,6 @@ #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" -#include "utilities/ticks.hpp" -#if INCLUDE_JFR -#include "jfr/jfr.hpp" -#include "jfr/jfrEvents.hpp" -#endif volatile size_t ClassLoaderDataGraph::_num_array_classes = 0; volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0; @@ -1325,29 +1320,6 @@ } #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. bool ClassLoaderDataGraph::do_unloading(bool do_cleaning) { @@ -1391,10 +1363,6 @@ _unloading = dead; } - if (seen_dead_loader) { - JFR_ONLY(post_class_unload_events();) - } - log_debug(class, loader, data)("do_unloading: loaders processed %u, loaders removed %u", loaders_processed, loaders_removed); return seen_dead_loader; --- old/src/hotspot/share/classfile/systemDictionary.cpp 2018-08-23 18:48:19.532188787 -0400 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2018-08-23 18:48:19.101707767 -0400 @@ -47,6 +47,7 @@ #include "gc/shared/oopStorage.inline.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/interpreter.hpp" +#include "jfr/jfr.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" @@ -83,6 +84,7 @@ #include "services/diagnosticCommand.hpp" #include "services/threadService.hpp" #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_CDS #include "classfile/systemDictionaryShared.hpp" #endif @@ -1851,10 +1853,22 @@ { GCTraceTime(Debug, gc, phases) t("ClassLoaderData", gc_timer); +#if INCLUDE_JFR + // If unloading occurs, make sure time stamp is consistent. + if (Jfr::is_enabled()) { + InstanceKlass::set_class_unload_time(Ticks::now()); + } +#endif + // First, mark for unload all ClassLoaderData referencing a dead class loader. unloading_occurred = ClassLoaderDataGraph::do_unloading(do_cleaning); if (unloading_occurred) { ClassLoaderDataGraph::clean_module_and_package_info(); +#if INCLUDE_JFR + if (Jfr::is_enabled()) { + Jfr::on_unloading_classes(); + } +#endif } } --- old/src/hotspot/share/oops/instanceKlass.cpp 2018-08-23 18:48:20.979965069 -0400 +++ new/src/hotspot/share/oops/instanceKlass.cpp 2018-08-23 18:48:20.549286093 -0400 @@ -80,6 +80,13 @@ #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif +#if INCLUDE_JFR +#include "utilities/ticks.hpp" +#include "jfr/jfr.hpp" +#include "jfr/jfrEvents.hpp" +Ticks InstanceKlass::_class_unload_time; +#endif + #ifdef DTRACE_ENABLED @@ -2423,6 +2430,18 @@ // notify ClassLoadingService of class unload ClassLoadingService::notify_class_unloaded(ik); + +#if INCLUDE_JFR + if (Jfr::is_enabled()) { + assert(ik != NULL, "invariant"); + EventClassUnload event(UNTIMED); + event.set_endtime(class_unload_time()); + event.set_unloadedClass(ik); + event.set_definingClassLoader(ik->class_loader_data()); + event.commit(); + } +#endif + } void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) { --- old/src/hotspot/share/oops/instanceKlass.hpp 2018-08-23 18:48:22.447358608 -0400 +++ new/src/hotspot/share/oops/instanceKlass.hpp 2018-08-23 18:48:22.018898651 -0400 @@ -41,6 +41,7 @@ #include "utilities/align.hpp" #include "utilities/macros.hpp" #if INCLUDE_JFR +#include "utilities/ticks.hpp" #include "jfr/support/jfrKlassExtension.hpp" #endif @@ -142,6 +143,11 @@ private: static InstanceKlass* allocate_instance_klass(const ClassFileParser& parser, TRAPS); +#if INCLUDE_JFR + // JFR Class unloading timestamp + static Ticks _class_unload_time; +#endif + protected: // If you add a new field that points to any metaspace object, you // must add this field to InstanceKlass::metaspace_pointers_do(). @@ -426,6 +432,11 @@ _transitive_interfaces = a; } +#if INCLUDE_JFR + static void set_class_unload_time(Ticks ticks) { _class_unload_time = ticks; } + static Ticks class_unload_time() { return _class_unload_time; } +#endif + private: friend class fieldDescriptor; FieldInfo* field(int index) const { return FieldInfo::from_field_array(_fields, index); }