Skip to content

Commit eb2488f

Browse files
calvinccheungVladimir Ivanov
andcommitted
8330198: Add some class loading related perf counters to measure VM startup
Co-authored-by: Vladimir Ivanov <[email protected]> Reviewed-by: iklam, dholmes
1 parent c4702ca commit eb2488f

File tree

14 files changed

+154
-16
lines changed

14 files changed

+154
-16
lines changed

src/hotspot/share/cds/dynamicArchive.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "cds/classPrelinker.hpp"
3232
#include "cds/dynamicArchive.hpp"
3333
#include "cds/regeneratedClasses.hpp"
34+
#include "classfile/classLoader.hpp"
3435
#include "classfile/classLoaderData.inline.hpp"
3536
#include "classfile/symbolTable.hpp"
3637
#include "classfile/systemDictionaryShared.hpp"
@@ -118,6 +119,9 @@ class DynamicArchiveBuilder : public ArchiveBuilder {
118119
return;
119120
}
120121

122+
log_info(cds,dynamic)("CDS dynamic dump: clinit = " JLONG_FORMAT "ms)",
123+
ClassLoader::class_init_time_ms());
124+
121125
init_header();
122126
gather_source_objs();
123127
gather_array_klasses();

src/hotspot/share/classfile/classLoader.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include "utilities/classpathStream.hpp"
7979
#include "utilities/events.hpp"
8080
#include "utilities/macros.hpp"
81+
#include "utilities/ostream.hpp"
8182
#include "utilities/utf8.hpp"
8283

8384
// Entry point in java.dll for path canonicalization
@@ -118,9 +119,40 @@ PerfCounter* ClassLoader::_perf_define_appclass_time = nullptr;
118119
PerfCounter* ClassLoader::_perf_define_appclass_selftime = nullptr;
119120
PerfCounter* ClassLoader::_perf_app_classfile_bytes_read = nullptr;
120121
PerfCounter* ClassLoader::_perf_sys_classfile_bytes_read = nullptr;
122+
PerfCounter* ClassLoader::_perf_ik_link_methods_time = nullptr;
123+
PerfCounter* ClassLoader::_perf_method_adapters_time = nullptr;
124+
PerfCounter* ClassLoader::_perf_ik_link_methods_count = nullptr;
125+
PerfCounter* ClassLoader::_perf_method_adapters_count = nullptr;
121126
PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = nullptr;
122127
PerfCounter* ClassLoader::_perf_secondary_hash_time = nullptr;
123128

129+
PerfCounter* ClassLoader::_perf_resolve_indy_time = nullptr;
130+
PerfCounter* ClassLoader::_perf_resolve_invokehandle_time = nullptr;
131+
PerfCounter* ClassLoader::_perf_resolve_mh_time = nullptr;
132+
PerfCounter* ClassLoader::_perf_resolve_mt_time = nullptr;
133+
134+
PerfCounter* ClassLoader::_perf_resolve_indy_count = nullptr;
135+
PerfCounter* ClassLoader::_perf_resolve_invokehandle_count = nullptr;
136+
PerfCounter* ClassLoader::_perf_resolve_mh_count = nullptr;
137+
PerfCounter* ClassLoader::_perf_resolve_mt_count = nullptr;
138+
139+
void ClassLoader::print_counters(outputStream *st) {
140+
// The counters are only active if the logging is enabled, but
141+
// we print to the passed in outputStream as requested.
142+
if (log_is_enabled(Info, perf, class, link)) {
143+
st->print_cr("ClassLoader:");
144+
st->print_cr(" clinit: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", ClassLoader::class_init_time_ms(), ClassLoader::class_init_count());
145+
st->print_cr(" link methods: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", Management::ticks_to_ms(_perf_ik_link_methods_time->get_value()) , _perf_ik_link_methods_count->get_value());
146+
st->print_cr(" method adapters: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", Management::ticks_to_ms(_perf_method_adapters_time->get_value()) , _perf_method_adapters_count->get_value());
147+
st->print_cr(" resolve...");
148+
st->print_cr(" invokedynamic: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", Management::ticks_to_ms(_perf_resolve_indy_time->get_value()) , _perf_resolve_indy_count->get_value());
149+
st->print_cr(" invokehandle: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", Management::ticks_to_ms(_perf_resolve_invokehandle_time->get_value()) , _perf_resolve_invokehandle_count->get_value());
150+
st->print_cr(" CP_MethodHandle: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", Management::ticks_to_ms(_perf_resolve_mh_time->get_value()) , _perf_resolve_mh_count->get_value());
151+
st->print_cr(" CP_MethodType: " JLONG_FORMAT "ms / " JLONG_FORMAT " events", Management::ticks_to_ms(_perf_resolve_mt_time->get_value()) , _perf_resolve_mt_count->get_value());
152+
st->cr();
153+
}
154+
}
155+
124156
GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = nullptr;
125157
GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = nullptr;
126158
ClassPathEntry* ClassLoader::_jrt_entry = nullptr;
@@ -1336,9 +1368,25 @@ void ClassLoader::initialize(TRAPS) {
13361368
NEWPERFTICKCOUNTER(_perf_define_appclass_selftime, SUN_CLS, "defineAppClassTime.self");
13371369
NEWPERFBYTECOUNTER(_perf_app_classfile_bytes_read, SUN_CLS, "appClassBytes");
13381370
NEWPERFBYTECOUNTER(_perf_sys_classfile_bytes_read, SUN_CLS, "sysClassBytes");
1339-
13401371
NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS, "unsafeDefineClassCalls");
13411372
NEWPERFTICKCOUNTER(_perf_secondary_hash_time, SUN_CLS, "secondarySuperHashTime");
1373+
1374+
if (log_is_enabled(Info, perf, class, link)) {
1375+
NEWPERFTICKCOUNTER(_perf_ik_link_methods_time, SUN_CLS, "linkMethodsTime");
1376+
NEWPERFTICKCOUNTER(_perf_method_adapters_time, SUN_CLS, "makeAdaptersTime");
1377+
NEWPERFEVENTCOUNTER(_perf_ik_link_methods_count, SUN_CLS, "linkMethodsCount");
1378+
NEWPERFEVENTCOUNTER(_perf_method_adapters_count, SUN_CLS, "makeAdaptersCount");
1379+
1380+
NEWPERFTICKCOUNTER(_perf_resolve_indy_time, SUN_CLS, "resolve_invokedynamic_time");
1381+
NEWPERFTICKCOUNTER(_perf_resolve_invokehandle_time, SUN_CLS, "resolve_invokehandle_time");
1382+
NEWPERFTICKCOUNTER(_perf_resolve_mh_time, SUN_CLS, "resolve_MethodHandle_time");
1383+
NEWPERFTICKCOUNTER(_perf_resolve_mt_time, SUN_CLS, "resolve_MethodType_time");
1384+
1385+
NEWPERFEVENTCOUNTER(_perf_resolve_indy_count, SUN_CLS, "resolve_invokedynamic_count");
1386+
NEWPERFEVENTCOUNTER(_perf_resolve_invokehandle_count, SUN_CLS, "resolve_invokehandle_count");
1387+
NEWPERFEVENTCOUNTER(_perf_resolve_mh_count, SUN_CLS, "resolve_MethodHandle_count");
1388+
NEWPERFEVENTCOUNTER(_perf_resolve_mt_count, SUN_CLS, "resolve_MethodType_count");
1389+
}
13421390
}
13431391

13441392
// lookup java library entry points

src/hotspot/share/classfile/classLoader.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "runtime/perfDataTypes.hpp"
3131
#include "utilities/exceptions.hpp"
3232
#include "utilities/macros.hpp"
33+
#include "utilities/ostream.hpp"
3334
#include "utilities/zipLibrary.hpp"
3435

3536
// The VM class loader.
@@ -166,6 +167,20 @@ class ClassLoader: AllStatic {
166167
static PerfCounter* _perf_define_appclass_selftime;
167168
static PerfCounter* _perf_app_classfile_bytes_read;
168169
static PerfCounter* _perf_sys_classfile_bytes_read;
170+
static PerfCounter* _perf_ik_link_methods_time;
171+
static PerfCounter* _perf_method_adapters_time;
172+
static PerfCounter* _perf_ik_link_methods_count;
173+
static PerfCounter* _perf_method_adapters_count;
174+
175+
static PerfCounter* _perf_resolve_indy_time;
176+
static PerfCounter* _perf_resolve_invokehandle_time;
177+
static PerfCounter* _perf_resolve_mh_time;
178+
static PerfCounter* _perf_resolve_mt_time;
179+
180+
static PerfCounter* _perf_resolve_indy_count;
181+
static PerfCounter* _perf_resolve_invokehandle_count;
182+
static PerfCounter* _perf_resolve_mh_count;
183+
static PerfCounter* _perf_resolve_mt_count;
169184

170185
static PerfCounter* _unsafe_defineClassCallCounter;
171186

@@ -285,6 +300,23 @@ class ClassLoader: AllStatic {
285300
static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; }
286301
static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; }
287302

303+
static PerfCounter* perf_ik_link_methods_time() { return _perf_ik_link_methods_time; }
304+
static PerfCounter* perf_method_adapters_time() { return _perf_method_adapters_time; }
305+
static PerfCounter* perf_ik_link_methods_count() { return _perf_ik_link_methods_count; }
306+
static PerfCounter* perf_method_adapters_count() { return _perf_method_adapters_count; }
307+
308+
static PerfCounter* perf_resolve_invokedynamic_time() { return _perf_resolve_indy_time; }
309+
static PerfCounter* perf_resolve_invokehandle_time() { return _perf_resolve_invokehandle_time; }
310+
static PerfCounter* perf_resolve_method_handle_time() { return _perf_resolve_mh_time; }
311+
static PerfCounter* perf_resolve_method_type_time() { return _perf_resolve_mt_time; }
312+
313+
static PerfCounter* perf_resolve_invokedynamic_count() { return _perf_resolve_indy_count; }
314+
static PerfCounter* perf_resolve_invokehandle_count() { return _perf_resolve_invokehandle_count; }
315+
static PerfCounter* perf_resolve_method_handle_count() { return _perf_resolve_mh_count; }
316+
static PerfCounter* perf_resolve_method_type_count() { return _perf_resolve_mt_count; }
317+
318+
static void print_counters(outputStream *st);
319+
288320
// Record how many calls to Unsafe_DefineClass
289321
static PerfCounter* unsafe_defineClassCallCounter() {
290322
return _unsafe_defineClassCallCounter;

src/hotspot/share/interpreter/linkResolver.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "precompiled.hpp"
2626
#include "cds/archiveUtils.hpp"
27+
#include "classfile/classLoader.hpp"
2728
#include "classfile/defaultMethods.hpp"
2829
#include "classfile/javaClasses.hpp"
2930
#include "classfile/systemDictionary.hpp"
@@ -55,7 +56,8 @@
5556
#include "runtime/fieldDescriptor.inline.hpp"
5657
#include "runtime/frame.inline.hpp"
5758
#include "runtime/handles.inline.hpp"
58-
#include "runtime/javaThread.hpp"
59+
#include "runtime/javaThread.inline.hpp"
60+
#include "runtime/perfData.hpp"
5961
#include "runtime/reflection.hpp"
6062
#include "runtime/safepointVerifiers.hpp"
6163
#include "runtime/sharedRuntime.hpp"
@@ -1728,6 +1730,10 @@ bool LinkResolver::resolve_previously_linked_invokehandle(CallInfo& result, cons
17281730
}
17291731

17301732
void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
1733+
1734+
PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokehandle_time(),
1735+
ClassLoader::perf_resolve_invokehandle_count());
1736+
17311737
LinkInfo link_info(pool, index, Bytecodes::_invokehandle, CHECK);
17321738
if (log_is_enabled(Info, methodhandles)) {
17331739
ResourceMark rm(THREAD);
@@ -1779,6 +1785,9 @@ void LinkResolver::resolve_handle_call(CallInfo& result,
17791785
}
17801786

17811787
void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int indy_index, TRAPS) {
1788+
PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokedynamic_time(),
1789+
ClassLoader::perf_resolve_invokedynamic_count());
1790+
17821791
int pool_index = pool->resolved_indy_entry_at(indy_index)->constant_pool_index();
17831792

17841793
// Resolve the bootstrap specifier (BSM + optional arguments).

src/hotspot/share/logging/logTag.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class outputStream;
110110
LOG_TAG(jvmti) \
111111
LOG_TAG(lambda) \
112112
LOG_TAG(library) \
113+
LOG_TAG(link) \
113114
LOG_TAG(liveness) \
114115
LOG_TAG(load) /* Trace all classes loaded */ \
115116
LOG_TAG(loader) \

src/hotspot/share/oops/constantPool.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "cds/cdsConfig.hpp"
3030
#include "cds/classPrelinker.hpp"
3131
#include "cds/heapShared.hpp"
32+
#include "classfile/classLoader.hpp"
3233
#include "classfile/classLoaderData.hpp"
3334
#include "classfile/javaClasses.inline.hpp"
3435
#include "classfile/metadataOnStackMark.hpp"
@@ -62,7 +63,8 @@
6263
#include "runtime/handles.inline.hpp"
6364
#include "runtime/init.hpp"
6465
#include "runtime/javaCalls.hpp"
65-
#include "runtime/javaThread.hpp"
66+
#include "runtime/javaThread.inline.hpp"
67+
#include "runtime/perfData.hpp"
6668
#include "runtime/signature.hpp"
6769
#include "runtime/vframe.inline.hpp"
6870
#include "utilities/checkedCast.hpp"
@@ -1014,7 +1016,9 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp,
10141016
}
10151017

10161018
case JVM_CONSTANT_Dynamic:
1017-
{
1019+
{ PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokedynamic_time(),
1020+
ClassLoader::perf_resolve_invokedynamic_count());
1021+
10181022
// Resolve the Dynamically-Computed constant to invoke the BSM in order to obtain the resulting oop.
10191023
BootstrapInfo bootstrap_specifier(this_cp, cp_index);
10201024

@@ -1072,7 +1076,9 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp,
10721076
break;
10731077

10741078
case JVM_CONSTANT_MethodHandle:
1075-
{
1079+
{ PerfTraceTimedEvent timer(ClassLoader::perf_resolve_method_handle_time(),
1080+
ClassLoader::perf_resolve_method_handle_count());
1081+
10761082
int ref_kind = this_cp->method_handle_ref_kind_at(cp_index);
10771083
int callee_index = this_cp->method_handle_klass_index_at(cp_index);
10781084
Symbol* name = this_cp->method_handle_name_ref_at(cp_index);
@@ -1120,7 +1126,9 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp,
11201126
}
11211127

11221128
case JVM_CONSTANT_MethodType:
1123-
{
1129+
{ PerfTraceTimedEvent timer(ClassLoader::perf_resolve_method_type_time(),
1130+
ClassLoader::perf_resolve_method_type_count());
1131+
11241132
Symbol* signature = this_cp->method_type_signature_at(cp_index);
11251133
{ ResourceMark rm(THREAD);
11261134
log_debug(class, resolve)("resolve JVM_CONSTANT_MethodType [%d/%d] %s",

src/hotspot/share/oops/instanceKlass.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,8 @@ void InstanceKlass::rewrite_class(TRAPS) {
978978
// This is outside is_rewritten flag. In case of an exception, it can be
979979
// executed more than once.
980980
void InstanceKlass::link_methods(TRAPS) {
981+
PerfTraceTime timer(ClassLoader::perf_ik_link_methods_time());
982+
981983
int len = methods()->length();
982984
for (int i = len-1; i >= 0; i--) {
983985
methodHandle m(THREAD, methods()->at(i));

src/hotspot/share/oops/method.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "cds/cdsConfig.hpp"
2727
#include "cds/cppVtables.hpp"
2828
#include "cds/metaspaceShared.hpp"
29+
#include "classfile/classLoader.hpp"
2930
#include "classfile/classLoaderDataGraph.hpp"
3031
#include "classfile/metadataOnStackMark.hpp"
3132
#include "classfile/symbolTable.hpp"
@@ -62,12 +63,14 @@
6263
#include "prims/jvmtiExport.hpp"
6364
#include "prims/methodHandles.hpp"
6465
#include "runtime/atomic.hpp"
66+
#include "runtime/arguments.hpp"
6567
#include "runtime/continuationEntry.hpp"
6668
#include "runtime/frame.inline.hpp"
6769
#include "runtime/handles.inline.hpp"
6870
#include "runtime/init.hpp"
6971
#include "runtime/java.hpp"
7072
#include "runtime/orderAccess.hpp"
73+
#include "runtime/perfData.hpp"
7174
#include "runtime/relocator.hpp"
7275
#include "runtime/safepointVerifiers.hpp"
7376
#include "runtime/sharedRuntime.hpp"
@@ -1168,6 +1171,10 @@ void Method::remove_unshareable_flags() {
11681171
// Called when the method_holder is getting linked. Setup entrypoints so the method
11691172
// is ready to be called from interpreter, compiler, and vtables.
11701173
void Method::link_method(const methodHandle& h_method, TRAPS) {
1174+
if (log_is_enabled(Info, perf, class, link)) {
1175+
ClassLoader::perf_ik_link_methods_count()->inc();
1176+
}
1177+
11711178
// If the code cache is full, we may reenter this function for the
11721179
// leftover methods that weren't linked.
11731180
if (adapter() != nullptr) {
@@ -1219,6 +1226,8 @@ void Method::link_method(const methodHandle& h_method, TRAPS) {
12191226
}
12201227

12211228
address Method::make_adapters(const methodHandle& mh, TRAPS) {
1229+
PerfTraceTime timer(ClassLoader::perf_method_adapters_time());
1230+
12221231
// Adapters for compiled code are made eagerly here. They are fairly
12231232
// small (generally < 100 bytes) and quick to make (and cached and shared)
12241233
// so making them eagerly shouldn't be too expensive.

src/hotspot/share/runtime/arguments.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3729,6 +3729,13 @@ jint Arguments::apply_ergo() {
37293729
}
37303730
#endif // COMPILER2_OR_JVMCI
37313731

3732+
if (log_is_enabled(Info, perf, class, link)) {
3733+
if (!UsePerfData) {
3734+
warning("Disabling -Xlog:perf+class+link since UsePerfData is turned off.");
3735+
LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(perf, class, link));
3736+
}
3737+
}
3738+
37323739
if (FLAG_IS_CMDLINE(DiagnoseSyncOnValueBasedClasses)) {
37333740
if (DiagnoseSyncOnValueBasedClasses == ObjectSynchronizer::LOG_WARNING && !log_is_enabled(Info, valuebasedclasses)) {
37343741
LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(valuebasedclasses));

src/hotspot/share/runtime/java.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "precompiled.hpp"
2626
#include "cds/cds_globals.hpp"
2727
#include "cds/dynamicArchive.hpp"
28+
#include "classfile/classLoader.hpp"
2829
#include "classfile/classLoaderDataGraph.hpp"
2930
#include "classfile/javaClasses.hpp"
3031
#include "classfile/stringTable.hpp"
@@ -156,7 +157,6 @@ static void print_method_profiling_data() {
156157
}
157158
}
158159

159-
160160
#ifndef PRODUCT
161161

162162
// Statistics printing (method invocation histogram)
@@ -356,6 +356,8 @@ void print_statistics() {
356356
}
357357

358358
ThreadsSMRSupport::log_statistics();
359+
360+
ClassLoader::print_counters(tty);
359361
}
360362

361363
// Note: before_exit() can be executed only once, if more than one threads

0 commit comments

Comments
 (0)