--- old/src/share/vm/classfile/systemDictionary.cpp 2013-04-15 09:51:43.415654100 +0200 +++ new/src/share/vm/classfile/systemDictionary.cpp 2013-04-15 09:51:41.840051300 +0200 @@ -54,7 +54,12 @@ #include "runtime/signature.hpp" #include "services/classLoadingService.hpp" #include "services/threadService.hpp" -#include "trace/traceMacros.hpp" + +#if INCLUDE_TRACE + #include "memory/iterator.hpp" + #include "trace/tracing.hpp" + #include "trace/traceMacros.hpp" +#endif Dictionary* SystemDictionary::_dictionary = NULL; @@ -581,6 +586,8 @@ assert(name != NULL && !FieldType::is_array(name) && !FieldType::is_obj(name), "invalid class name"); + jlong class_load_start_time = class_load_tracing_begin(); + // UseNewReflection // Fix for 4474172; see evaluation for more details class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); @@ -788,26 +795,29 @@ } } - // If everything was OK (no exceptions, no null return value), and - // class_loader is NOT the defining loader, do a little more bookkeeping. - if (!HAS_PENDING_EXCEPTION && !k.is_null() && - k->class_loader() != class_loader()) { - - check_constraints(d_index, d_hash, k, class_loader, false, THREAD); - - // Need to check for a PENDING_EXCEPTION again; check_constraints - // can throw and doesn't use the CHECK macro. - if (!HAS_PENDING_EXCEPTION) { - { // Grabbing the Compile_lock prevents systemDictionary updates - // during compilations. - MutexLocker mu(Compile_lock, THREAD); - update_dictionary(d_index, d_hash, p_index, p_hash, - k, class_loader, THREAD); - } - if (JvmtiExport::should_post_class_load()) { - Thread *thread = THREAD; - assert(thread->is_Java_thread(), "thread->is_Java_thread()"); - JvmtiExport::post_class_load((JavaThread *) thread, k()); + // If everything was OK (no exceptions, no null return value) + if (!HAS_PENDING_EXCEPTION && !k.is_null()) { + post_class_load_event(class_load_start_time, k, class_loader); + + // class_loader is NOT the defining loader, do a little more bookkeeping. + if (k->class_loader() != class_loader()) { + check_constraints(d_index, d_hash, k, class_loader, false, THREAD); + + // Need to check for a PENDING_EXCEPTION again; check_constraints + // can throw and doesn't use the CHECK macro. + if (!HAS_PENDING_EXCEPTION) { + { // Grabbing the Compile_lock prevents systemDictionary updates + // during compilations. + MutexLocker mu(Compile_lock, THREAD); + update_dictionary(d_index, d_hash, p_index, p_hash, + k, class_loader, THREAD); + } + + if (JvmtiExport::should_post_class_load()) { + Thread *thread = THREAD; + assert(thread->is_Java_thread(), "thread->is_Java_thread()"); + JvmtiExport::post_class_load((JavaThread *) thread, k()); + } } } } @@ -939,6 +949,8 @@ TRAPS) { TempNewSymbol parsed_name = NULL; + jlong class_load_start_time = class_load_tracing_begin(); + // Parse the stream. Note that we do this even though this klass might // already be present in the SystemDictionary, otherwise we would not // throw potential ClassFormatErrors. @@ -991,6 +1003,8 @@ k->eager_initialize(THREAD); + post_class_load_event(class_load_start_time, k, class_loader); + // notify jvmti if (JvmtiExport::should_post_class_load()) { assert(THREAD->is_Java_thread(), "thread->is_Java_thread()"); @@ -1654,7 +1668,9 @@ } return newsize; } + bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) { + post_class_unload_events(is_alive); bool result = dictionary()->do_unloading(is_alive); constraints()->purge_loader_constraints(is_alive); resolution_errors()->purge_resolution_errors(is_alive); @@ -2601,6 +2617,78 @@ "Loaded klasses should be in SystemDictionary"); } +jlong SystemDictionary::class_load_tracing_begin(void) { +#if INCLUDE_TRACE + return os::elapsed_counter(); +#endif + return 0; +} + +// utililty function for class load event +void SystemDictionary::post_class_load_event(jlong start_time, + instanceKlassHandle k, Handle initiating_loader) { +#if INCLUDE_TRACE + EventClassLoad event(UNTIMED); + if (event.should_commit()) { + event.set_endtime(os::elapsed_counter()); + event.set_starttime(start_time); + event.set_loadedClass(k()); + oop defining_class_loader = k->class_loader(); + event.set_definingClassLoader(defining_class_loader != NULL ? + defining_class_loader->klass() : NULL); + oop class_loader = initiating_loader.is_null() ? (oop)NULL : initiating_loader(); + event.set_initiatingClassLoader(class_loader != NULL ? + class_loader->klass() : NULL); + event.commit(); + } +#endif /* INCLUDE_TRACE */ +} + +void SystemDictionary::post_class_unload_events(BoolObjectClosure* is_alive) { +#if INCLUDE_TRACE + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); + if (Tracing::enabled()) { + _should_write_unload_events = Tracing::is_event_enabled(TraceClassUnloadEvent); + _class_unload_time = Tracing::time(); + _is_alive = is_alive; + classes_do(&class_unload_event); + + if (_no_of_classes_unloading > 0) { + Tracing::on_unloading_classes(is_alive, _no_of_classes_unloading); + _no_of_classes_unloading = 0; + } + _should_write_unload_events = false; + _is_alive = NULL; + } +#endif /* INCLUDE_TRACE */ +} + +#if INCLUDE_TRACE +TracingTime SystemDictionary::_class_unload_time; +BoolObjectClosure* SystemDictionary::_is_alive = NULL; +int SystemDictionary::_no_of_classes_unloading = 0; +bool SystemDictionary::_should_write_unload_events = false; + +void SystemDictionary::class_unload_event(klassOop curklass) { + + Klass* myklass = curklass->klass_part(); + oop class_loader = myklass->class_loader(); + + if (class_loader != NULL && _is_alive != NULL && !_is_alive->do_object_b(class_loader)) { + _no_of_classes_unloading++; + if (_should_write_unload_events) { + // post class unload event + EventClassUnload event(UNTIMED); + event.set_endtime(_class_unload_time); + event.set_unloadedClass(curklass); + event.set_definingClassLoader(class_loader->klass()); + event.commit(); + } + } +} + +#endif /* INCLUDE_TRACE */ + #ifndef PRODUCT // statistics code --- old/src/share/vm/classfile/systemDictionary.hpp 2013-04-15 09:51:50.061265800 +0200 +++ new/src/share/vm/classfile/systemDictionary.hpp 2013-04-15 09:51:49.296864400 +0200 @@ -34,6 +34,11 @@ #include "utilities/hashtable.hpp" #include "utilities/hashtable.inline.hpp" +#if INCLUDE_TRACE + #include "trace/traceTime.hpp" + class BoolObjectClosure; +#endif + // The system dictionary stores all loaded classes and maps: // // [class name,class loader] -> class i.e. [Symbol*,oop] -> klassOop @@ -607,6 +612,10 @@ static void check_loader_lock_contention(Handle loader_lock, TRAPS); static bool is_parallelCapable(Handle class_loader); static bool is_parallelDefine(Handle class_loader); + static jlong class_load_tracing_begin(void); + static void post_class_load_event(jlong start_time, instanceKlassHandle k, + Handle initiating_loader); + static void post_class_unload_events(BoolObjectClosure* is_alive); static klassOop find_shared_class(Symbol* class_name); @@ -669,6 +678,14 @@ static bool _has_loadClassInternal; static bool _has_checkPackageAccess; + +#if INCLUDE_TRACE + static TracingTime _class_unload_time; + static BoolObjectClosure* _is_alive; + static int _no_of_classes_unloading; + static bool _should_write_unload_events; + static void class_unload_event(klassOop curklass); +#endif }; class SystemDictionaryHandles : AllStatic { --- old/src/share/vm/gc_implementation/shared/gcTraceSend.cpp 2013-04-15 09:51:55.302875000 +0200 +++ new/src/share/vm/gc_implementation/shared/gcTraceSend.cpp 2013-04-15 09:51:54.554073700 +0200 @@ -136,7 +136,7 @@ bool GCTracer::should_send_object_count_after_gc_event() const { #if INCLUDE_TRACE - return Tracing::enabled(EventObjectCountAfterGC::eventId); + return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId); #else return false; #endif --- old/src/share/vm/runtime/objectMonitor.cpp 2013-04-15 09:52:01.012485000 +0200 +++ new/src/share/vm/runtime/objectMonitor.cpp 2013-04-15 09:52:00.232483700 +0200 @@ -973,7 +973,7 @@ #if INCLUDE_TRACE // get the owner's thread id for the MonitorEnter event // if it is enabled and the thread isn't suspended - if (not_suspended && Tracing::enabled(TraceJavaMonitorEnterEvent)) { + if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) { _previous_owner_tid = SharedRuntime::get_java_tid(Self); } #endif --- old/src/share/vm/trace/trace.xml 2013-04-15 09:52:06.425694500 +0200 +++ new/src/share/vm/trace/trace.xml 2013-04-15 09:52:05.630093100 +0200 @@ -1,6 +1,6 @@