Skip to content

Commit 295f686

Browse files
author
duke
committed
Backport a349944
1 parent 3db8262 commit 295f686

24 files changed

+202
-174
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ InstanceKlass* JfrClassTransformer::create_new_instance_klass(InstanceKlass* ik,
132132
}
133133

134134
// Redefining / retransforming?
135-
const Klass* JfrClassTransformer::find_existing_klass(const InstanceKlass* ik, JavaThread* thread) {
135+
const InstanceKlass* JfrClassTransformer::find_existing_klass(const InstanceKlass* ik, JavaThread* thread) {
136136
assert(ik != nullptr, "invariant");
137137
assert(thread != nullptr, "invariant");
138138
JvmtiThreadState* const state = thread->jvmti_thread_state();
139139
return state != nullptr ? klass_being_redefined(ik, state) : nullptr;
140140
}
141141

142-
const Klass* JfrClassTransformer::klass_being_redefined(const InstanceKlass* ik, JvmtiThreadState* state) {
142+
const InstanceKlass* JfrClassTransformer::klass_being_redefined(const InstanceKlass* ik, JvmtiThreadState* state) {
143143
assert(ik != nullptr, "invariant");
144144
assert(state != nullptr, "invariant");
145145
const GrowableArray<Klass*>* const redef_klasses = state->get_classes_being_redefined();
@@ -149,9 +149,10 @@ const Klass* JfrClassTransformer::klass_being_redefined(const InstanceKlass* ik,
149149
for (int i = 0; i < redef_klasses->length(); ++i) {
150150
const Klass* const existing_klass = redef_klasses->at(i);
151151
assert(existing_klass != nullptr, "invariant");
152+
assert(existing_klass->is_instance_klass(), "invariant");
152153
if (ik->name() == existing_klass->name() && ik->class_loader_data() == existing_klass->class_loader_data()) {
153154
// 'ik' is a scratch klass. Return the klass being redefined.
154-
return existing_klass;
155+
return InstanceKlass::cast(existing_klass);
155156
}
156157
}
157158
return nullptr;

src/hotspot/share/jfr/instrumentation/jfrClassTransformer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class InstanceKlass;
3838
class JfrClassTransformer : AllStatic {
3939
private:
4040
static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStream* stream, TRAPS);
41-
static const Klass* klass_being_redefined(const InstanceKlass* ik, JvmtiThreadState* state);
41+
static const InstanceKlass* klass_being_redefined(const InstanceKlass* ik, JvmtiThreadState* state);
4242

4343
public:
44-
static const Klass* find_existing_klass(const InstanceKlass* ik, JavaThread* thread);
44+
static const InstanceKlass* find_existing_klass(const InstanceKlass* ik, JavaThread* thread);
4545
static InstanceKlass* create_instance_klass(InstanceKlass*& ik, ClassFileStream* stream, bool is_initial_load, JavaThread* thread);
4646
static void copy_traceid(const InstanceKlass* ik, const InstanceKlass* new_ik);
4747
static void transfer_cached_class_file_data(InstanceKlass* ik, InstanceKlass* new_ik, const ClassFileParser& parser, JavaThread* thread);

src/hotspot/share/jfr/jfr.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "jfr/support/jfrResolution.hpp"
3737
#include "jfr/support/jfrThreadLocal.hpp"
3838
#include "jfr/support/methodtracer/jfrMethodTracer.hpp"
39+
#include "jfr/support/methodtracer/jfrTraceTagging.hpp"
3940
#include "oops/instanceKlass.hpp"
4041
#include "oops/instanceKlass.inline.hpp"
4142
#include "oops/klass.hpp"
@@ -88,12 +89,10 @@ void Jfr::on_klass_creation(InstanceKlass*& ik, ClassFileParser& parser, TRAPS)
8889
}
8990
}
9091

91-
void Jfr::on_klass_redefinition(const InstanceKlass* ik, Thread* thread) {
92-
assert(JfrMethodTracer::in_use(), "invariant");
93-
JfrMethodTracer::on_klass_redefinition(ik, thread);
92+
void Jfr::on_klass_redefinition(const InstanceKlass* ik, const InstanceKlass* scratch_klass) {
93+
JfrTraceTagging::on_klass_redefinition(ik, scratch_klass);
9494
}
9595

96-
9796
bool Jfr::is_excluded(Thread* t) {
9897
return JfrJavaSupport::is_excluded(t);
9998
}

src/hotspot/share/jfr/jfr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class Jfr : AllStatic {
6161
static void include_thread(Thread* thread);
6262
static void exclude_thread(Thread* thread);
6363
static void on_klass_creation(InstanceKlass*& ik, ClassFileParser& parser, TRAPS);
64-
static void on_klass_redefinition(const InstanceKlass* ik, Thread* thread);
64+
static void on_klass_redefinition(const InstanceKlass* ik, const InstanceKlass* scratch_klass);
6565
static void on_thread_start(Thread* thread);
6666
static void on_thread_exit(Thread* thread);
6767
static void on_resolution(const CallInfo& info, TRAPS);

src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,8 +533,9 @@ static void clear_method_tracer_klasses() {
533533
static void do_unloading_klass(Klass* klass) {
534534
assert(klass != nullptr, "invariant");
535535
assert(_subsystem_callback != nullptr, "invariant");
536-
if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_scratch_class()) {
537-
return;
536+
if (!used(klass) && klass->is_instance_klass() && InstanceKlass::cast(klass)->is_scratch_class()) {
537+
SET_TRANSIENT(klass);
538+
assert(used(klass), "invariant");
538539
}
539540
if (JfrKlassUnloading::on_unload(klass)) {
540541
if (JfrTraceId::has_sticky_bit(klass)) {

src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class MethodUsedPredicate {
152152
if (!klass->is_instance_klass()) {
153153
return false;
154154
}
155-
return _current_epoch ? METHOD_USED_THIS_EPOCH(klass) : METHOD_USED_PREVIOUS_EPOCH(klass);
155+
return _current_epoch ? USED_THIS_EPOCH(klass) : USED_PREVIOUS_EPOCH(klass);
156156
}
157157
};
158158

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "memory/allStatic.hpp"
3131

3232
class ClassLoaderData;
33+
class InstanceKlass;
3334
class Klass;
3435
class Method;
3536
class ModuleEntry;
@@ -86,7 +87,6 @@ class JfrTraceId : public AllStatic {
8687

8788
// through load barrier
8889
static traceid load(const Klass* klass);
89-
static traceid load_previous_epoch(const Klass* klass);
9090
static traceid load(jclass jc, bool raw = false);
9191
static traceid load(const Method* method);
9292
static traceid load(const Klass* klass, const Method* method);
@@ -146,10 +146,8 @@ class JfrTraceId : public AllStatic {
146146
static void set_sticky_bit(const Method* method);
147147
static void clear_sticky_bit(const Klass* k);
148148
static void clear_sticky_bit(const Method* method);
149-
static bool has_timing_bit(const Klass* k);
150-
static void set_timing_bit(const Klass* k);
151-
static void clear_timing_bit(const Klass* k);
152-
149+
static bool has_timing_bit(const InstanceKlass* scratch_klass);
150+
static void set_timing_bit(const InstanceKlass* scratch_klass);
153151
};
154152

155153
#endif // SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEID_HPP

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp"
3333
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp"
3434
#include "jfr/support/jfrKlassExtension.hpp"
35+
#include "oops/instanceKlass.hpp"
3536
#include "oops/klass.hpp"
3637
#include "runtime/javaThread.inline.hpp"
3738
#include "runtime/mutexLocker.hpp"
@@ -81,10 +82,6 @@ inline traceid JfrTraceId::load_leakp_previous_epoch(const Klass* klass, const M
8182
return JfrTraceIdLoadBarrier::load_leakp_previous_epoch(klass, method);
8283
}
8384

84-
inline traceid JfrTraceId::load_previous_epoch(const Klass* klass) {
85-
return JfrTraceIdLoadBarrier::load_previous_epoch(klass);
86-
}
87-
8885
template <typename T>
8986
inline traceid raw_load(const T* t) {
9087
assert(t != nullptr, "invariant");
@@ -198,37 +195,30 @@ inline void JfrTraceId::set_sticky_bit(const Method* method) {
198195
assert(method != nullptr, "invariant");
199196
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
200197
assert(!has_sticky_bit(method), "invariant");
198+
assert(!method->is_old(), "invariant");
201199
SET_METHOD_STICKY_BIT(method);
202200
assert(has_sticky_bit(method), "invariant");
203201
}
204202

205203
inline void JfrTraceId::clear_sticky_bit(const Method* method) {
206204
assert(method != nullptr, "invarriant");
207205
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
206+
assert(!method->is_old(), "invariant");
208207
assert(JfrTraceId::has_sticky_bit(method), "invariant");
209208
CLEAR_STICKY_BIT_METHOD(method);
210209
assert(!JfrTraceId::has_sticky_bit(method), "invariant");
211210
}
212211

213-
inline bool JfrTraceId::has_timing_bit(const Klass* k) {
214-
assert(k != nullptr, "invariant");
215-
return HAS_TIMING_BIT(k);
212+
inline bool JfrTraceId::has_timing_bit(const InstanceKlass* scratch_klass) {
213+
assert(scratch_klass != nullptr, "invariant");
214+
return HAS_TIMING_BIT(scratch_klass);
216215
}
217216

218-
inline void JfrTraceId::set_timing_bit(const Klass* k) {
219-
assert(k != nullptr, "invariant");
220-
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
221-
assert(!has_timing_bit(k), "invariant");
222-
SET_TIMING_BIT(k);
223-
assert(has_timing_bit(k), "invariant");
224-
}
225-
226-
inline void JfrTraceId::clear_timing_bit(const Klass* k) {
227-
assert(k != nullptr, "invarriant");
228-
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
229-
assert(JfrTraceId::has_timing_bit(k), "invariant");
230-
CLEAR_TIMING_BIT(k);
231-
assert(!JfrTraceId::has_timing_bit(k), "invariant");
217+
inline void JfrTraceId::set_timing_bit(const InstanceKlass* scratch_klass) {
218+
assert(scratch_klass != nullptr, "invariant");
219+
assert(!has_timing_bit(scratch_klass), "invariant");
220+
SET_TIMING_BIT(scratch_klass);
221+
assert(has_timing_bit(scratch_klass), "invariant");
232222
}
233223

234224
#endif // SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEID_INLINE_HPP

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.inline.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,7 @@ inline uint8_t* traceid_meta_byte(const T* ptr) {
7878
template <>
7979
inline uint8_t* traceid_meta_byte<Method>(const Method* ptr) {
8080
assert(ptr != nullptr, "invariant");
81-
return ptr->trace_meta_addr();
81+
return ptr->trace_flags_meta_addr();
8282
}
8383

8484
inline uint8_t traceid_and(uint8_t bits, uint8_t current) {

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,37 @@ inline traceid JfrTraceIdLoadBarrier::load(const Klass* klass) {
8686
return TRACE_ID(klass);
8787
}
8888

89+
inline const Method* latest_version(const Klass* klass, const Method* method) {
90+
assert(klass != nullptr, "invariant");
91+
assert(method != nullptr, "invariant");
92+
assert(klass == method->method_holder(), "invariant");
93+
assert(method->is_old(), "invariant");
94+
const InstanceKlass* const ik = InstanceKlass::cast(klass);
95+
assert(ik->has_been_redefined(), "invariant");
96+
const Method* const latest_version = ik->method_with_orig_idnum(method->orig_method_idnum());
97+
if (latest_version == nullptr) {
98+
assert(AllowRedefinitionToAddDeleteMethods, "invariant");
99+
// method has been removed. Return old version.
100+
return method;
101+
}
102+
assert(latest_version != nullptr, "invariant");
103+
assert(latest_version != method, "invariant");
104+
assert(!latest_version->is_old(), "invariant");
105+
assert(latest_version->orig_method_idnum() == method->orig_method_idnum(), "invariant");
106+
assert(latest_version->name() == method->name() && latest_version->signature() == method->signature(), "invariant");
107+
return latest_version;
108+
}
109+
89110
inline traceid JfrTraceIdLoadBarrier::load(const Method* method) {
90111
return load(method->method_holder(), method);
91112
}
92113

93114
inline traceid JfrTraceIdLoadBarrier::load(const Klass* klass, const Method* method) {
94115
assert(klass != nullptr, "invariant");
95116
assert(method != nullptr, "invariant");
117+
if (method->is_old()) {
118+
method = latest_version(klass, method);
119+
}
96120
if (should_tag(method)) {
97121
SET_METHOD_AND_CLASS_USED_THIS_EPOCH(klass);
98122
SET_METHOD_FLAG_USED_THIS_EPOCH(method);
@@ -111,6 +135,9 @@ inline traceid JfrTraceIdLoadBarrier::load_no_enqueue(const Method* method) {
111135
inline traceid JfrTraceIdLoadBarrier::load_no_enqueue(const Klass* klass, const Method* method) {
112136
assert(klass != nullptr, "invariant");
113137
assert(method != nullptr, "invariant");
138+
if (method->is_old()) {
139+
method = latest_version(klass, method);
140+
}
114141
SET_METHOD_AND_CLASS_USED_THIS_EPOCH(klass);
115142
SET_METHOD_FLAG_USED_THIS_EPOCH(method);
116143
assert(METHOD_AND_CLASS_USED_THIS_EPOCH(klass), "invariant");
@@ -123,11 +150,12 @@ inline traceid JfrTraceIdLoadBarrier::load(const ClassLoaderData* cld) {
123150
if (cld->has_class_mirror_holder()) {
124151
return 0;
125152
}
153+
const traceid id = set_used_and_get(cld);
126154
const Klass* const class_loader_klass = cld->class_loader_klass();
127155
if (class_loader_klass != nullptr) {
128156
load(class_loader_klass);
129157
}
130-
return set_used_and_get(cld);
158+
return id;
131159
}
132160

133161
inline traceid JfrTraceIdLoadBarrier::load(const ModuleEntry* module) {
@@ -158,6 +186,7 @@ inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass) {
158186
inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass, const Method* method) {
159187
assert(klass != nullptr, "invariant");
160188
assert(method != nullptr, "invariant");
189+
assert(!method->is_old(), "invariant");
161190
assert(klass == method->method_holder(), "invariant");
162191
assert(METHOD_AND_CLASS_USED_THIS_EPOCH(klass), "invariant");
163192
if (should_tag(method)) {
@@ -175,6 +204,7 @@ inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass, const Metho
175204
inline traceid JfrTraceIdLoadBarrier::load_leakp_previous_epoch(const Klass* klass, const Method* method) {
176205
assert(klass != nullptr, "invariant");
177206
assert(method != nullptr, "invariant");
207+
assert(!method->is_old(), "invariant");
178208
assert(klass == method->method_holder(), "invariant");
179209
assert(METHOD_AND_CLASS_USED_PREVIOUS_EPOCH(klass), "invariant");
180210
if (METHOD_FLAG_NOT_USED_PREVIOUS_EPOCH(method)) {

0 commit comments

Comments
 (0)