From 3b427b4702ac1ccdfa47fc46522fc06884abf394 Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Fri, 16 Dec 2022 09:23:41 +0800
Subject: [PATCH 24/33] I68TO2: Print class loading details when enable
 TraceClassLoading
---
 hotspot/src/share/vm/classfile/classFileParser.cpp | 25 +++++++++++++++++++---
 hotspot/src/share/vm/runtime/globals.hpp           |  8 +++++++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index ae91995..3ec6aec 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -4323,9 +4323,28 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
     if (TraceClassLoading) {
       ResourceMark rm;
       // print in a single call to reduce interleaving of output
-      if (cfs->source() != NULL) {
-        tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
-                   cfs->source());
+      const char* source = cfs->source();
+      if (source != NULL && PrintClassLoadingDetails) {
+        tty->date_stamp(true);
+        OSThread* osThread = THREAD->osthread();
+        if (osThread != NULL) {
+          tty->print("%d ", osThread->thread_id());
+        }
+        const char* loader_name = class_loader.is_null()
+                                ? "bootstrap"
+                                : InstanceKlass::cast(class_loader->klass())->external_name();
+        const char* klass_name = this_klass->external_name();
+        tty->print(" [Loaded %s from %s by classloader %s]\n", klass_name,
+                   source, loader_name);
+        if (PrintThreadStackOnLoadingClass != NULL && klass_name != NULL &&
+            strstr(klass_name, PrintThreadStackOnLoadingClass) && THREAD->is_Java_thread()) {
+          JavaThread* javaThread = ((JavaThread*) THREAD);
+          javaThread->print_on(tty);
+          javaThread->print_stack_on(tty);
+        }
+      } else if (source != NULL) {
+          tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
+                     source);
       } else if (class_loader.is_null()) {
         Klass* caller =
             THREAD->is_Java_thread()
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index d1e3cda..14c3c89 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -951,6 +951,14 @@ class CommandLineFlags {
   product(ccstrlist, OnOutOfMemoryError, "",                                \
           "Run user-defined commands on first java.lang.OutOfMemoryError")  \
                                                                             \
+  manageable(bool, PrintClassLoadingDetails, false,                         \
+          "Print class loading details (including date stamps, thread id "  \
+          "and effective class loaders) when enable TraceClassLoading")     \
+                                                                            \
+  manageable(ccstr, PrintThreadStackOnLoadingClass, NULL,                   \
+          "Print thread stack when the specified class is loaded when "     \
+          "enable PrintClassLoadingDetails")                                \
+                                                                            \
   manageable(bool, HeapDumpBeforeFullGC, false,                             \
           "Dump heap to file before any major stop-the-world GC")           \
                                                                             \
--
1.8.3.1
