src/share/vm/classfile/classLoaderData.cpp
Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
*** 62,71 ****
--- 62,76 ----
#include "runtime/safepoint.hpp"
#include "runtime/synchronizer.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/ostream.hpp"
+ #if INCLUDE_TRACE
+ #include "trace/tracing.hpp"
+ #endif
+
+
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
_class_loader(h_class_loader()),
_is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially
*** 118,127 ****
--- 123,138 ----
klass_closure->do_klass(k);
assert(k != k->next_link(), "no loops!");
}
}
+ void ClassLoaderData::classes_do(void f(Klass * const)) {
+ for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
+ f(k);
+ }
+ }
+
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
if (k->oop_is_instance()) {
f(InstanceKlass::cast(k));
}
*** 581,590 ****
--- 592,614 ----
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
cld->classes_do(klass_closure);
}
}
+ void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
+ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ cld->classes_do(f);
+ }
+ }
+
+ 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()) {
+ cld->classes_do(f);
+ }
+ }
+
GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() {
assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?");
GrowableArray<ClassLoaderData*>* array = new GrowableArray<ClassLoaderData*>();
*** 685,694 ****
--- 709,723 ----
_head = data;
}
dead->set_next(_unloading);
_unloading = dead;
}
+
+ if (seen_dead_loader) {
+ post_class_unload_events();
+ }
+
return seen_dead_loader;
}
void ClassLoaderDataGraph::purge() {
ClassLoaderData* list = _unloading;
*** 700,709 ****
--- 729,752 ----
delete purge_me;
}
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 = Tracing::time();
+ classes_unloading_do(&class_unload_event);
+ }
+ Tracing::on_unloading_classes();
+ }
+ #endif
+ }
+
// CDS support
// Global metaspaces for writing information to the shared archive. When
// application CDS is supported, we may need one per metaspace, so this
// sort of looks like it.
*** 767,771 ****
--- 810,832 ----
} else {
out->print("class loader "PTR_FORMAT, this);
class_loader()->print_value_on(out);
}
}
+
+ #if INCLUDE_TRACE
+
+ TracingTime 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 */