diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 9e1e2644cf5..3d99dd2abb4 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -2372,7 +2372,18 @@ void PrintClassClosure::do_klass(Klass* k) { if (ik->is_rewritten()) buf[i++] = 'W'; if (ik->is_contended()) buf[i++] = 'C'; if (ik->has_been_redefined()) buf[i++] = 'R'; - if (ik->in_aot_cache()) buf[i++] = 'S'; + if (ik->in_aot_cache()) { + buf[i++] = 'S'; + + if (AOTMetaspace::in_aot_cache_static_region((void*)k)) { + _aot_statics++; + if (_location) buf[i++] = 's'; + } else if (AOTMetaspace::in_aot_cache_dynamic_region((void*)k)) { + _aot_dynamics++; + if (_location) buf[i++] = 'd'; + } + } + } buf[i++] = '\0'; _st->print("%-7s ", buf); diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 72310dcb0c5..2950538354e 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1211,6 +1211,9 @@ private: bool _verbose; bool _location; public: + unsigned int _aot_statics; + unsigned int _aot_dynamics; + PrintClassClosure(outputStream* st, bool verbose, bool location); void do_klass(Klass* k); diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index fbb539bacbc..f098435a763 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -25,6 +25,7 @@ #include "cds/aotMetaspace.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" +#include "cds/filemap.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/classLoaderHierarchyDCmd.hpp" #include "classfile/classLoaderStats.hpp" @@ -957,9 +958,9 @@ ClassesDCmd::ClassesDCmd(outputStream* output, bool heap) : "W = methods rewritten, " "C = marked with @Contended annotation, " "R = has been redefined, " - "S = is shared class", + "S = is shared class (if -location then 's' indicates static 'd' indicates dynamic AOT cache)", "BOOLEAN", false, "false"), - _location("-location", "Print class file location url (if available)", "BOOLEAN", false, "false") { + _location("-location", "Print class file (and AOT cache) location url (if available)", "BOOLEAN", false, "false") { _dcmdparser.add_dcmd_option(&_verbose); _dcmdparser.add_dcmd_option(&_location); } @@ -977,6 +978,13 @@ public: virtual void doit() { PrintClassClosure closure(_out, _verbose, _location); ClassLoaderDataGraph::classes_do(&closure); + + if (_location) { + if (closure._aot_statics > 0) + _out->print_cr("\n%d classes shared from static cache: %s", closure._aot_statics, FileMapInfo::current_info()->full_path()); + if (closure._aot_dynamics > 0) + _out->print_cr("\n%d classes shared from dynamic cache: %s", closure._aot_dynamics, FileMapInfo::dynamic_info()->full_path()); + } } }; diff --git a/src/jdk.jcmd/share/man/jcmd.md b/src/jdk.jcmd/share/man/jcmd.md index 3a8f0ac3828..5f5f11da73a 100644 --- a/src/jdk.jcmd/share/man/jcmd.md +++ b/src/jdk.jcmd/share/man/jcmd.md @@ -800,16 +800,25 @@ The following commands are available: *options*: - `-verbose`: (Optional) Dump the detailed content of a Java class. - Some classes are annotated with flags: `F` = has, or inherits, a non-empty finalize method, - `f` = has final method, `W` = methods rewritten, `C` = marked with `@Contended` annotation, - `R` = has been redefined, `S` = is shared class (BOOLEAN, false) + Some classes are annotated with flags: + - `F` = has, or inherits, a non-empty finalize method, + - `f` = has final method, + - `W` = methods rewritten, + - `C` = marked with `@Contended` annotation, + - `R` = has been redefined, + - `S` = is shared class (if -location 's' is static and 'd' is dynamic AOT cache location) + (BOOLEAN, false) - `-location`: (Optional) Print the location of the class file from which the class is loaded (if available) If provided by its defining ClassLoader, this option will print a URL specifying the location of the - class file (directory, jar or other URL location) from which this class was loaded. + class file (directory, jar or other URL location) from which this class was initially loaded. Note: JDK (and other classes) loaded by a ClassLoader that does not provide a location URL to the JVM will omit this field. + Note: if any classes are loaded from an AOT cache, their location reported is that of the original + url from which they were loaded at the time of the training run that created the AOT cache. + + The total number of classes loaded from any AOT cache (and its name) are summarized. `VM.classloader_stats` : Print statistics about all ClassLoaders.