src/share/vm/classfile/classLoaderData.cpp

Print this page
rev 12364 : 8170672: Event-based tracing to support classloader instances
Reviewed-by:

@@ -95,11 +95,11 @@
   _modules(NULL), _packages(NULL),
   _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
   _next(NULL), _dependencies(dependencies), _shared_class_loader_id(-1),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)) {
-    // empty
+  TRACE_INIT_ID(this);
 }
 
 void ClassLoaderData::init_dependencies(TRAPS) {
   assert(!Universe::is_fully_initialized(), "should only be called when initializing");
   assert(is_the_null_class_loader_data(), "should only call this for the null class loader");

@@ -165,13 +165,14 @@
     assert(k != k->next_link(), "no loops!");
   }
 }
 
 void ClassLoaderData::classes_do(void f(Klass * const)) {
-  assert_locked_or_safepoint(_metaspace_lock);
-  for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
+  // Lock-free access requires load_ptr_acquire
+  for (Klass* k = load_ptr_acquire(&_klasses); k != NULL; k = k->next_link()) {
     f(k);
+    assert(k != k->next_link(), "no loops!");
   }
 }
 
 void ClassLoaderData::methods_do(void f(Method*)) {
   // Lock-free access requires load_ptr_acquire

@@ -810,10 +811,20 @@
   for (ClassLoaderData* cld = _head; cl != NULL && cld != NULL; cld = cld->next()) {
     cl->do_cld(cld);
   }
 }
 
+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;
     if (closure != NULL) {
       closure->do_cld(cld);

@@ -1040,11 +1051,11 @@
     Metaspace::purge();
     set_metaspace_oom(false);
   }
 }
 
-void ClassLoaderDataGraph::post_class_unload_events(void) {
+void ClassLoaderDataGraph::post_class_unload_events() {
 #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!");

@@ -1189,12 +1200,10 @@
 
   // 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.set_definingClassLoader(k->class_loader_data());
   event.commit();
 }
 
 #endif // INCLUDE_TRACE