src/share/vm/classfile/classLoaderData.cpp

Print this page
rev 9245 : [mq]: class_loading_log

@@ -52,16 +52,18 @@
 #include "classfile/javaClasses.hpp"
 #include "classfile/metadataOnStackMark.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
 #include "gc/shared/gcLocker.hpp"
+#include "logging/log.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
+#include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/synchronizer.hpp"
 #include "utilities/growableArray.hpp"

@@ -280,13 +282,14 @@
   // Make sure linked class is stable, since the class list is walked without a lock
   OrderAccess::storestore();
   // link the new item into the list
   _klasses = k;
 
-  if (TraceClassLoaderData && Verbose && k->class_loader_data() != NULL) {
+  if (log_is_enabled(Trace, classloaderdata) && k->class_loader_data() != NULL) {
     ResourceMark rm;
-    tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: "
+    outputStream* log = LogHandle(classloaderdata)::trace_stream();
+    log->print_cr("Adding k: " PTR_FORMAT " %s to CLD: "
                   PTR_FORMAT " loader: " PTR_FORMAT " %s",
                   p2i(k),
                   k->external_name(),
                   p2i(k->class_loader_data()),
                   p2i((void *)k->class_loader()),

@@ -320,19 +323,20 @@
   _unloading = true;
 
   // Tell serviceability tools these classes are unloading
   classes_do(InstanceKlass::notify_unload_class);
 
-  if (TraceClassLoaderData) {
+  if (log_is_enabled(Debug, classloaderdata)) {
     ResourceMark rm;
-    tty->print("[ClassLoaderData: unload loader data " INTPTR_FORMAT, p2i(this));
-    tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()),
+    outputStream* log = LogHandle(classloaderdata)::debug_stream();
+    log->print(": unload loader data " INTPTR_FORMAT, p2i(this));
+    log->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()),
                loader_name());
     if (is_anonymous()) {
-      tty->print(" for anonymous class  " INTPTR_FORMAT " ", p2i(_klasses));
+      log->print(" for anonymous class  " INTPTR_FORMAT " ", p2i(_klasses));
     }
-    tty->print_cr("]");
+    log->cr();
   }
 }
 
 oop ClassLoaderData::keep_alive_object() const {
   assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");

@@ -402,17 +406,19 @@
     }
     if (this == the_null_class_loader_data()) {
       assert (class_loader() == NULL, "Must be");
       set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType));
     } else if (is_anonymous()) {
-      if (TraceClassLoaderData && Verbose && class_loader() != NULL) {
-        tty->print_cr("is_anonymous: %s", class_loader()->klass()->internal_name());
+      if (log_is_enabled(Trace, classloaderdata) && class_loader() != NULL) {
+        outputStream* log = LogHandle(classloaderdata)::trace_stream();
+        log->print_cr("is_anonymous: %s", class_loader()->klass()->internal_name());
       }
       set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType));
     } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
-      if (TraceClassLoaderData && Verbose && class_loader() != NULL) {
-        tty->print_cr("is_reflection: %s", class_loader()->klass()->internal_name());
+      if (log_is_enabled(Trace, classloaderdata) && class_loader() != NULL) {
+        outputStream* log = LogHandle(classloaderdata)::trace_stream();
+        log->print_cr("is_reflection: %s", class_loader()->klass()->internal_name());
       }
       set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType));
     } else {
       set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType));
     }

@@ -567,17 +573,20 @@
 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) {
   // We need to allocate all the oops for the ClassLoaderData before allocating the
   // actual ClassLoaderData object.
   ClassLoaderData::Dependencies dependencies(CHECK_NULL);
+  ClassLoaderData* cld;
 
+
+//BEGIN no_safepoints
+{
   No_Safepoint_Verifier no_safepoints; // we mustn't GC until we've installed the
                                        // ClassLoaderData in the graph since the CLD
                                        // contains unhandled oops
 
-  ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies);
-
+  cld = new ClassLoaderData(loader, is_anonymous, dependencies);
 
   if (!is_anonymous) {
     ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
     // First, Atomically set it
     ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);

@@ -595,23 +604,48 @@
 
   do {
     cld->set_next(next);
     ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
     if (exchanged == next) {
-      if (TraceClassLoaderData) {
-        ResourceMark rm;
-        tty->print("[ClassLoaderData: ");
-        tty->print("create class loader data " INTPTR_FORMAT, p2i(cld));
-        tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()),
-                   cld->loader_name());
-        tty->print_cr("]");
-      }
-      return cld;
+      break;
     }
     next = exchanged;
   } while (true);
+ }
+//END no_safepoints
 
+  // It's OK to do safe points now (and we need to do that in JavaCalls::call_virtual)
+  if (log_is_enabled(Debug, classloaderdata)) {
+    Handle string;
+    if (loader.not_null()) {
+      // Include the result of loader.toString() in the output. This allows
+      // the user of the log to identify the class loader instance.
+      JavaValue result(T_OBJECT);
+      KlassHandle spec_klass(THREAD, SystemDictionary::ClassLoader_klass());
+      JavaCalls::call_virtual(&result,
+                              loader,
+                              spec_klass,
+                              vmSymbols::toString_name(),
+                              vmSymbols::void_string_signature(),
+                              CHECK_NULL);
+      assert(result.get_type() == T_OBJECT, "just checking");
+      string = (oop)result.get_jobject();
+    }
+
+    ResourceMark rm;
+    outputStream* log = LogHandle(classloaderdata)::debug_stream();
+    log->print("create class loader data " INTPTR_FORMAT, p2i(cld));
+    log->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()),
+               cld->loader_name());
+
+    if (string.not_null()) {
+      log->print(": ");
+      java_lang_String::print(string(), log);
+    }
+    log->cr();
+  }
+  return cld;
 }
 
 void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
     cld->oops_do(f, klass_closure, must_claim);

@@ -703,14 +737,15 @@
   ClassLoaderData* curr = _head;
   while (curr != _saved_head) {
     if (!curr->claimed()) {
       array->push(curr);
 
-      if (TraceClassLoaderData) {
-        tty->print("[ClassLoaderData] found new CLD: ");
-        curr->print_value_on(tty);
-        tty->cr();
+      if (log_is_enabled(Debug, classloaderdata)) {
+        outputStream* log = LogHandle(classloaderdata)::debug_stream();
+        log->print("[ClassLoaderData] found new CLD: ");
+        curr->print_value_on(log);
+        log->cr();
       }
     }
 
     curr = curr->_next;
   }