Skip to content

Commit e93b10d

Browse files
author
Markus Grönlund
committed
8365400: Enhance JFR to emit file and module metadata for class loading
Reviewed-by: coleenp, egahlin
1 parent 8d80778 commit e93b10d

33 files changed

+1210
-337
lines changed

src/hotspot/share/cds/lambdaProxyClassDictionary.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ InstanceKlass* LambdaProxyClassDictionary::load_and_init_lambda_proxy_class(Inst
357357
InstanceKlass* nest_host = caller_ik->nest_host(THREAD);
358358
assert(nest_host == shared_nest_host, "mismatched nest host");
359359

360-
EventClassLoad class_load_start_event;
360+
EventClassLoad class_load_event;
361361

362362
// Add to class hierarchy, and do possible deoptimizations.
363363
lambda_ik->add_to_hierarchy(THREAD);
@@ -368,8 +368,8 @@ InstanceKlass* LambdaProxyClassDictionary::load_and_init_lambda_proxy_class(Inst
368368
if (JvmtiExport::should_post_class_load()) {
369369
JvmtiExport::post_class_load(THREAD, lambda_ik);
370370
}
371-
if (class_load_start_event.should_commit()) {
372-
SystemDictionary::post_class_load_event(&class_load_start_event, lambda_ik, ClassLoaderData::class_loader_data(class_loader()));
371+
if (class_load_event.should_commit()) {
372+
JFR_ONLY(SystemDictionary::post_class_load_event(&class_load_event, lambda_ik, ClassLoaderData::class_loader_data(class_loader()));)
373373
}
374374

375375
lambda_ik->initialize(CHECK_NULL);

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@
8989
#if INCLUDE_CDS
9090
#include "classfile/systemDictionaryShared.hpp"
9191
#endif
92-
#if INCLUDE_JFR
93-
#include "jfr/support/jfrTraceIdExtension.hpp"
94-
#endif
9592

9693
// We generally try to create the oops directly when parsing, rather than
9794
// allocating temporary data structures and copying the bytes twice. A
@@ -5272,8 +5269,6 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik,
52725269
}
52735270
}
52745271

5275-
JFR_ONLY(INIT_ID(ik);)
5276-
52775272
// If we reach here, all is well.
52785273
// Now remove the InstanceKlass* from the _klass_to_deallocate field
52795274
// in order for it to not be destroyed in the ClassFileParser destructor.

src/hotspot/share/classfile/classFileParser.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ class ClassFileParser {
500500

501501
InstanceKlass* create_instance_klass(bool cf_changed_in_CFLH, const ClassInstanceInfo& cl_inst_info, TRAPS);
502502

503+
const ClassFileStream& stream() const { return *_stream; }
504+
503505
const ClassFileStream* clone_stream() const;
504506

505507
void set_klass_to_deallocate(InstanceKlass* klass);

src/hotspot/share/classfile/klassFactory.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "runtime/handles.inline.hpp"
3838
#include "utilities/macros.hpp"
3939
#if INCLUDE_JFR
40-
#include "jfr/support/jfrKlassExtension.hpp"
40+
#include "jfr/jfr.hpp"
4141
#endif
4242

4343

@@ -99,6 +99,9 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
9999
new_ik->set_classpath_index(path_index);
100100
}
101101

102+
103+
JFR_ONLY(Jfr::on_klass_creation(new_ik, parser, THREAD);)
104+
102105
return new_ik;
103106
}
104107
}
@@ -213,7 +216,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
213216
result->set_cached_class_file(cached_class_file);
214217
}
215218

216-
JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
219+
JFR_ONLY(Jfr::on_klass_creation(result, parser, THREAD);)
217220

218221
#if INCLUDE_CDS
219222
if (CDSConfig::is_dumping_archive()) {

src/hotspot/share/classfile/systemDictionary.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -560,15 +560,6 @@ static InstanceKlass* handle_parallel_loading(JavaThread* current,
560560
return nullptr;
561561
}
562562

563-
void SystemDictionary::post_class_load_event(EventClassLoad* event, const InstanceKlass* k, const ClassLoaderData* init_cld) {
564-
assert(event != nullptr, "invariant");
565-
assert(k != nullptr, "invariant");
566-
event->set_loadedClass(k);
567-
event->set_definingClassLoader(k->class_loader_data());
568-
event->set_initiatingClassLoader(init_cld);
569-
event->commit();
570-
}
571-
572563
// SystemDictionary::resolve_instance_class_or_null is the main function for class name resolution.
573564
// After checking if the InstanceKlass already exists, it checks for ClassCircularityError and
574565
// whether the thread must wait for loading in parallel. It eventually calls load_instance_class,
@@ -582,7 +573,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
582573
assert(name != nullptr && !Signature::is_array(name) &&
583574
!Signature::has_envelope(name), "invalid class name: %s", name == nullptr ? "nullptr" : name->as_C_string());
584575

585-
EventClassLoad class_load_start_event;
576+
EventClassLoad class_load_event;
586577

587578
HandleMark hm(THREAD);
588579

@@ -713,8 +704,8 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
713704
return nullptr;
714705
}
715706

716-
if (class_load_start_event.should_commit()) {
717-
post_class_load_event(&class_load_start_event, loaded_class, loader_data);
707+
if (class_load_event.should_commit()) {
708+
JFR_ONLY(post_class_load_event(&class_load_event, loaded_class, loader_data);)
718709
}
719710

720711
// Make sure we have the right class in the dictionary
@@ -789,7 +780,7 @@ InstanceKlass* SystemDictionary::resolve_hidden_class_from_stream(
789780
const ClassLoadInfo& cl_info,
790781
TRAPS) {
791782

792-
EventClassLoad class_load_start_event;
783+
EventClassLoad class_load_event;
793784
ClassLoaderData* loader_data;
794785

795786
// - for hidden classes that are not strong: create a new CLD that has a class holder and
@@ -819,15 +810,16 @@ InstanceKlass* SystemDictionary::resolve_hidden_class_from_stream(
819810
k->add_to_hierarchy(THREAD);
820811
// But, do not add to dictionary.
821812

813+
if (class_load_event.should_commit()) {
814+
JFR_ONLY(post_class_load_event(&class_load_event, k, loader_data);)
815+
}
816+
822817
k->link_class(CHECK_NULL);
823818

824819
// notify jvmti
825820
if (JvmtiExport::should_post_class_load()) {
826821
JvmtiExport::post_class_load(THREAD, k);
827822
}
828-
if (class_load_start_event.should_commit()) {
829-
post_class_load_event(&class_load_start_event, k, loader_data);
830-
}
831823

832824
return k;
833825
}
@@ -1154,6 +1146,17 @@ void SystemDictionary::load_shared_class_misc(InstanceKlass* ik, ClassLoaderData
11541146
}
11551147
}
11561148

1149+
#if INCLUDE_JFR
1150+
void SystemDictionary::post_class_load_event(EventClassLoad* event, const InstanceKlass* k, const ClassLoaderData* init_cld) {
1151+
assert(event != nullptr, "invariant");
1152+
assert(k != nullptr, "invariant");
1153+
event->set_loadedClass(k);
1154+
event->set_definingClassLoader(k->class_loader_data());
1155+
event->set_initiatingClassLoader(init_cld);
1156+
event->commit();
1157+
}
1158+
#endif // INCLUDE_JFR
1159+
11571160
// This is much more lightweight than SystemDictionary::resolve_or_null
11581161
// - There's only a single Java thread at this point. No need for placeholder.
11591162
// - All supertypes of ik have been loaded
@@ -1182,6 +1185,8 @@ void SystemDictionary::preload_class(Handle class_loader, InstanceKlass* ik, TRA
11821185
}
11831186
#endif
11841187

1188+
EventClassLoad class_load_event;
1189+
11851190
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
11861191
oop java_mirror = ik->archived_java_mirror();
11871192
precond(java_mirror != nullptr);
@@ -1203,6 +1208,10 @@ void SystemDictionary::preload_class(Handle class_loader, InstanceKlass* ik, TRA
12031208
update_dictionary(THREAD, ik, loader_data);
12041209
}
12051210

1211+
if (class_load_event.should_commit()) {
1212+
JFR_ONLY(post_class_load_event(&class_load_event, ik, loader_data);)
1213+
}
1214+
12061215
assert(ik->is_loaded(), "Must be in at least loaded state");
12071216
}
12081217

@@ -1380,15 +1389,6 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* name,
13801389
return loaded_class;
13811390
}
13821391

1383-
static void post_class_define_event(InstanceKlass* k, const ClassLoaderData* def_cld) {
1384-
EventClassDefine event;
1385-
if (event.should_commit()) {
1386-
event.set_definedClass(k);
1387-
event.set_definingClassLoader(def_cld);
1388-
event.commit();
1389-
}
1390-
}
1391-
13921392
void SystemDictionary::define_instance_class(InstanceKlass* k, Handle class_loader, TRAPS) {
13931393

13941394
ClassLoaderData* loader_data = k->class_loader_data();
@@ -1440,7 +1440,6 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, Handle class_load
14401440
if (JvmtiExport::should_post_class_load()) {
14411441
JvmtiExport::post_class_load(THREAD, k);
14421442
}
1443-
post_class_define_event(k, loader_data);
14441443
}
14451444

14461445
// Support parallel classloading

src/hotspot/share/classfile/systemDictionary.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,10 @@ class SystemDictionary : AllStatic {
326326
static void restore_archived_method_handle_intrinsics_impl(TRAPS) NOT_CDS_RETURN;
327327

328328
protected:
329-
// Used by AOTLinkedClassBulkLoader, LambdaProxyClassDictionary, and SystemDictionaryShared
329+
// Used by AOTLinkedClassBulkLoader, LambdaProxyClassDictionary, VMClasses and SystemDictionaryShared
330330

331331
static bool add_loader_constraint(Symbol* name, Klass* klass_being_linked, Handle loader1,
332332
Handle loader2);
333-
static void post_class_load_event(EventClassLoad* event, const InstanceKlass* k, const ClassLoaderData* init_cld);
334333
static InstanceKlass* load_shared_class(InstanceKlass* ik,
335334
Handle class_loader,
336335
Handle protection_domain,
@@ -342,6 +341,9 @@ class SystemDictionary : AllStatic {
342341
static InstanceKlass* find_or_define_instance_class(Symbol* class_name,
343342
Handle class_loader,
344343
InstanceKlass* k, TRAPS);
344+
JFR_ONLY(static void post_class_load_event(EventClassLoad* event,
345+
const InstanceKlass* k,
346+
const ClassLoaderData* init_cld);)
345347

346348
public:
347349
static bool is_system_class_loader(oop class_loader);

src/hotspot/share/classfile/vmClasses.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "classfile/vmClasses.hpp"
3636
#include "classfile/vmSymbols.hpp"
3737
#include "gc/shared/collectedHeap.hpp"
38+
#include "jfr/jfrEvents.hpp"
3839
#include "memory/metaspaceClosure.hpp"
3940
#include "memory/universe.hpp"
4041
#include "oops/instanceKlass.hpp"
@@ -240,6 +241,8 @@ void vmClasses::resolve_shared_class(InstanceKlass* klass, ClassLoaderData* load
240241
return;
241242
}
242243

244+
EventClassLoad class_load_event;
245+
243246
// add super and interfaces first
244247
InstanceKlass* super = klass->super();
245248
if (super != nullptr && super->class_loader_data() == nullptr) {
@@ -261,6 +264,10 @@ void vmClasses::resolve_shared_class(InstanceKlass* klass, ClassLoaderData* load
261264
dictionary->add_klass(THREAD, klass->name(), klass);
262265
klass->add_to_hierarchy(THREAD);
263266
assert(klass->is_loaded(), "Must be in at least loaded state");
267+
268+
if (class_load_event.should_commit()) {
269+
JFR_ONLY(SystemDictionary::post_class_load_event(&class_load_event, klass, loader_data);)
270+
}
264271
}
265272

266273
#endif // INCLUDE_CDS

src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1427,10 +1427,10 @@ static void transform(InstanceKlass*& ik, ClassFileParser& parser, JavaThread* t
14271427
} else {
14281428
JfrClassTransformer::cache_class_file_data(new_ik, stream, thread);
14291429
}
1430+
JfrClassTransformer::copy_traceid(ik, new_ik);
14301431
if (is_instrumented && JdkJfrEvent::is_subklass(new_ik)) {
14311432
bless_commit_method(new_ik);
14321433
}
1433-
JfrClassTransformer::copy_traceid(ik, new_ik);
14341434
JfrClassTransformer::rewrite_klass_pointer(ik, new_ik, parser, thread);
14351435
}
14361436

src/hotspot/share/jfr/jfr.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*
2323
*/
2424

25+
#include "classfile/classFileParser.hpp"
2526
#include "jfr/instrumentation/jfrEventClassTransformer.hpp"
2627
#include "jfr/jfr.hpp"
2728
#include "jfr/jni/jfrJavaSupport.hpp"
@@ -31,6 +32,7 @@
3132
#include "jfr/recorder/repository/jfrEmergencyDump.hpp"
3233
#include "jfr/recorder/repository/jfrRepository.hpp"
3334
#include "jfr/recorder/service/jfrOptionSet.hpp"
35+
#include "jfr/support/jfrClassDefineEvent.hpp"
3436
#include "jfr/support/jfrKlassExtension.hpp"
3537
#include "jfr/support/jfrResolution.hpp"
3638
#include "jfr/support/jfrThreadLocal.hpp"
@@ -78,13 +80,15 @@ void Jfr::on_unloading_classes() {
7880
}
7981

8082
void Jfr::on_klass_creation(InstanceKlass*& ik, ClassFileParser& parser, TRAPS) {
83+
JfrTraceId::assign(ik);
8184
if (IS_EVENT_OR_HOST_KLASS(ik)) {
8285
JfrEventClassTransformer::on_klass_creation(ik, parser, THREAD);
83-
return;
84-
}
85-
if (JfrMethodTracer::in_use()) {
86+
} else if (JfrMethodTracer::in_use()) {
8687
JfrMethodTracer::on_klass_creation(ik, parser, THREAD);
8788
}
89+
if (!parser.is_internal()) {
90+
JfrClassDefineEvent::on_creation(ik, parser, THREAD);
91+
}
8892
}
8993

9094
void Jfr::on_klass_redefinition(const InstanceKlass* ik, const InstanceKlass* scratch_klass) {
@@ -168,3 +172,11 @@ bool Jfr::on_flight_recorder_option(const JavaVMOption** option, char* delimiter
168172
bool Jfr::on_start_flight_recording_option(const JavaVMOption** option, char* delimiter) {
169173
return JfrOptionSet::parse_start_flight_recording_option(option, delimiter);
170174
}
175+
176+
void Jfr::on_restoration(const Klass* k, JavaThread* jt) {
177+
assert(k != nullptr, "invariant");
178+
JfrTraceId::restore(k);
179+
if (k->is_instance_klass()) {
180+
JfrClassDefineEvent::on_restoration(InstanceKlass::cast(k), jt);
181+
}
182+
}

src/hotspot/share/jfr/jfr.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#ifndef SHARE_JFR_JFR_HPP
2626
#define SHARE_JFR_JFR_HPP
2727

28+
#include "jfr/utilities/jfrTypes.hpp"
2829
#include "memory/allStatic.hpp"
2930
#include "oops/oopsHierarchy.hpp"
3031
#include "utilities/exceptions.hpp"
@@ -78,6 +79,7 @@ class Jfr : AllStatic {
7879
static void initialize_main_thread(JavaThread* jt);
7980
static bool has_sample_request(JavaThread* jt);
8081
static void check_and_process_sample_request(JavaThread* jt);
82+
static void on_restoration(const Klass* k, JavaThread* jt);
8183
};
8284

8385
#endif // SHARE_JFR_JFR_HPP

0 commit comments

Comments
 (0)