Skip to content

Commit 9c2ab6e

Browse files
Merge tag 'jdk-23+31' into ola/24.1_jdk-23+31
Added tag jdk-23+31 for changeset 6720685
2 parents cf69742 + 6720685 commit 9c2ab6e

File tree

61 files changed

+1832
-370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1832
-370
lines changed

src/hotspot/share/classfile/classLoaderDataGraph.cpp

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -241,22 +241,23 @@ LockedClassesDo::~LockedClassesDo() {
241241

242242

243243
// Iterating over the CLDG needs to be locked because
244-
// unloading can remove entries concurrently soon.
245-
template <bool keep_alive = true>
246-
class ClassLoaderDataGraphIteratorBase : public StackObj {
244+
// unloading can remove entries concurrently.
245+
// This iterator does not keep the CLD alive.
246+
// Any CLD OopHandles (modules, mirrors, resolved refs)
247+
// resolved must be treated as no keepalive. And requires
248+
// that its CLD's holder is kept alive if they escape the
249+
// caller's safepoint or ClassLoaderDataGraph_lock
250+
// critical section.
251+
class ClassLoaderDataGraph::ClassLoaderDataGraphIterator : public StackObj {
247252
ClassLoaderData* _next;
248253
Thread* _thread;
249254
HandleMark _hm; // clean up handles when this is done.
250255
NoSafepointVerifier _nsv; // No safepoints allowed in this scope
251256
// unless verifying at a safepoint.
252257

253258
public:
254-
ClassLoaderDataGraphIteratorBase() : _next(ClassLoaderDataGraph::_head), _thread(Thread::current()), _hm(_thread) {
255-
if (keep_alive) {
256-
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
257-
} else {
258-
assert_at_safepoint();
259-
}
259+
ClassLoaderDataGraphIterator() : _next(ClassLoaderDataGraph::_head), _thread(Thread::current()), _hm(_thread) {
260+
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
260261
}
261262

262263
ClassLoaderData* get_next() {
@@ -266,10 +267,6 @@ class ClassLoaderDataGraphIteratorBase : public StackObj {
266267
cld = cld->next();
267268
}
268269
if (cld != nullptr) {
269-
if (keep_alive) {
270-
// Keep cld that is being returned alive.
271-
Handle(_thread, cld->holder());
272-
}
273270
_next = cld->next();
274271
} else {
275272
_next = nullptr;
@@ -278,23 +275,13 @@ class ClassLoaderDataGraphIteratorBase : public StackObj {
278275
}
279276
};
280277

281-
using ClassLoaderDataGraphIterator = ClassLoaderDataGraphIteratorBase<true /* keep_alive */>;
282-
using ClassLoaderDataGraphIteratorNoKeepAlive = ClassLoaderDataGraphIteratorBase<false /* keep_alive */>;
283-
284278
void ClassLoaderDataGraph::loaded_cld_do(CLDClosure* cl) {
285279
ClassLoaderDataGraphIterator iter;
286280
while (ClassLoaderData* cld = iter.get_next()) {
287281
cl->do_cld(cld);
288282
}
289283
}
290284

291-
void ClassLoaderDataGraph::loaded_cld_do_no_keepalive(CLDClosure* cl) {
292-
ClassLoaderDataGraphIteratorNoKeepAlive iter;
293-
while (ClassLoaderData* cld = iter.get_next()) {
294-
cl->do_cld(cld);
295-
}
296-
}
297-
298285
// These functions assume that the caller has locked the ClassLoaderDataGraph_lock
299286
// if they are not calling the function from a safepoint.
300287
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
@@ -318,6 +305,16 @@ void ClassLoaderDataGraph::methods_do(void f(Method*)) {
318305
}
319306
}
320307

308+
void ClassLoaderDataGraph::modules_do_keepalive(void f(ModuleEntry*)) {
309+
assert_locked_or_safepoint(Module_lock);
310+
ClassLoaderDataGraphIterator iter;
311+
while (ClassLoaderData* cld = iter.get_next()) {
312+
// Keep the holder alive.
313+
(void)cld->holder();
314+
cld->modules_do(f);
315+
}
316+
}
317+
321318
void ClassLoaderDataGraph::modules_do(void f(ModuleEntry*)) {
322319
assert_locked_or_safepoint(Module_lock);
323320
ClassLoaderDataGraphIterator iter;
@@ -334,9 +331,11 @@ void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) {
334331
}
335332
}
336333

337-
void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
334+
void ClassLoaderDataGraph::loaded_classes_do_keepalive(KlassClosure* klass_closure) {
338335
ClassLoaderDataGraphIterator iter;
339336
while (ClassLoaderData* cld = iter.get_next()) {
337+
// Keep the holder alive.
338+
(void)cld->holder();
340339
cld->loaded_classes_do(klass_closure);
341340
}
342341
}
@@ -346,34 +345,36 @@ void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
346345
}
347346

348347
void ClassLoaderDataGraph::verify_dictionary() {
349-
ClassLoaderDataGraphIteratorNoKeepAlive iter;
348+
ClassLoaderDataGraphIterator iter;
350349
while (ClassLoaderData* cld = iter.get_next()) {
351350
if (cld->dictionary() != nullptr) {
352351
cld->dictionary()->verify();
353352
}
354353
}
355354
}
356355

357-
#define FOR_ALL_DICTIONARY(X) ClassLoaderDataGraphIterator iter; \
358-
while (ClassLoaderData* X = iter.get_next()) \
359-
if (X->dictionary() != nullptr)
360-
361356
void ClassLoaderDataGraph::print_dictionary(outputStream* st) {
362-
FOR_ALL_DICTIONARY(cld) {
363-
st->print("Dictionary for ");
364-
cld->print_value_on(st);
365-
st->cr();
366-
cld->dictionary()->print_on(st);
367-
st->cr();
357+
ClassLoaderDataGraphIterator iter;
358+
while (ClassLoaderData *cld = iter.get_next()) {
359+
if (cld->dictionary() != nullptr) {
360+
st->print("Dictionary for ");
361+
cld->print_value_on(st);
362+
st->cr();
363+
cld->dictionary()->print_on(st);
364+
st->cr();
365+
}
368366
}
369367
}
370368

371369
void ClassLoaderDataGraph::print_table_statistics(outputStream* st) {
372-
FOR_ALL_DICTIONARY(cld) {
373-
ResourceMark rm; // loader_name_and_id
374-
stringStream tempst;
375-
tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
376-
cld->dictionary()->print_table_statistics(st, tempst.freeze());
370+
ClassLoaderDataGraphIterator iter;
371+
while (ClassLoaderData *cld = iter.get_next()) {
372+
if (cld->dictionary() != nullptr) {
373+
ResourceMark rm; // loader_name_and_id
374+
stringStream tempst;
375+
tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
376+
cld->dictionary()->print_table_statistics(st, tempst.freeze());
377+
}
377378
}
378379
}
379380

@@ -550,7 +551,7 @@ Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() {
550551
}
551552

552553
void ClassLoaderDataGraph::verify() {
553-
ClassLoaderDataGraphIteratorNoKeepAlive iter;
554+
ClassLoaderDataGraphIterator iter;
554555
while (ClassLoaderData* cld = iter.get_next()) {
555556
cld->verify();
556557
}

src/hotspot/share/classfile/classLoaderDataGraph.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ class ClassLoaderDataGraph : public AllStatic {
3737
friend class ClassLoaderDataGraphMetaspaceIterator;
3838
friend class ClassLoaderDataGraphKlassIteratorAtomic;
3939
friend class ClassLoaderDataGraphKlassIteratorStatic;
40-
template <bool keep_alive>
41-
friend class ClassLoaderDataGraphIteratorBase;
4240
friend class VMStructs;
4341
private:
42+
class ClassLoaderDataGraphIterator;
43+
4444
// All CLDs (except unlinked CLDs) can be reached by walking _head->_next->...
4545
static ClassLoaderData* volatile _head;
4646

@@ -71,8 +71,12 @@ class ClassLoaderDataGraph : public AllStatic {
7171
static void roots_cld_do(CLDClosure* strong, CLDClosure* weak);
7272
static void always_strong_cld_do(CLDClosure* cl);
7373
// Iteration through CLDG not by GC.
74+
// All the do suffixed functions do not keep the CLD alive. Any CLD OopHandles
75+
// (modules, mirrors, resolved refs) resolved must be treated as no keepalive.
76+
// And requires that its CLD's holder is kept alive if they escape the
77+
// caller's safepoint or ClassLoaderDataGraph_lock critical section.
78+
// The do_keepalive suffixed functions will keep all CLDs alive.
7479
static void loaded_cld_do(CLDClosure* cl);
75-
static void loaded_cld_do_no_keepalive(CLDClosure* cl);
7680
// klass do
7781
// Walking classes through the ClassLoaderDataGraph include array classes. It also includes
7882
// classes that are allocated but not loaded, classes that have errors, and scratch classes
@@ -81,9 +85,10 @@ class ClassLoaderDataGraph : public AllStatic {
8185
static void classes_do(KlassClosure* klass_closure);
8286
static void classes_do(void f(Klass* const));
8387
static void methods_do(void f(Method*));
88+
static void modules_do_keepalive(void f(ModuleEntry*));
8489
static void modules_do(void f(ModuleEntry*));
8590
static void packages_do(void f(PackageEntry*));
86-
static void loaded_classes_do(KlassClosure* klass_closure);
91+
static void loaded_classes_do_keepalive(KlassClosure* klass_closure);
8792
static void classes_unloading_do(void f(Klass* const));
8893
static bool do_unloading();
8994

src/hotspot/share/classfile/classLoaderStats.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
165165

166166
void ClassLoaderStatsVMOperation::doit() {
167167
ClassLoaderStatsClosure clsc (_out);
168-
ClassLoaderDataGraph::loaded_cld_do_no_keepalive(&clsc);
168+
ClassLoaderDataGraph::loaded_cld_do(&clsc);
169169
clsc.print();
170170
}
171171

src/hotspot/share/classfile/javaClasses.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ int java_lang_Class::_class_loader_offset;
788788
int java_lang_Class::_module_offset;
789789
int java_lang_Class::_protection_domain_offset;
790790
int java_lang_Class::_component_mirror_offset;
791+
int java_lang_Class::_init_lock_offset;
791792
int java_lang_Class::_signers_offset;
792793
int java_lang_Class::_name_offset;
793794
int java_lang_Class::_source_file_offset;
@@ -911,6 +912,12 @@ void java_lang_Class::initialize_mirror_fields(Klass* k,
911912
Handle protection_domain,
912913
Handle classData,
913914
TRAPS) {
915+
// Allocate a simple java object for a lock.
916+
// This needs to be a java object because during class initialization
917+
// it can be held across a java call.
918+
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
919+
set_init_lock(mirror(), r);
920+
914921
// Set protection domain also
915922
set_protection_domain(mirror(), protection_domain());
916923

@@ -1132,6 +1139,10 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
11321139
if (!k->is_array_klass()) {
11331140
// - local static final fields with initial values were initialized at dump time
11341141

1142+
// create the init_lock
1143+
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
1144+
set_init_lock(mirror(), r);
1145+
11351146
if (protection_domain.not_null()) {
11361147
set_protection_domain(mirror(), protection_domain());
11371148
}
@@ -1196,6 +1207,15 @@ oop java_lang_Class::component_mirror(oop java_class) {
11961207
return java_class->obj_field(_component_mirror_offset);
11971208
}
11981209

1210+
oop java_lang_Class::init_lock(oop java_class) {
1211+
assert(_init_lock_offset != 0, "must be set");
1212+
return java_class->obj_field(_init_lock_offset);
1213+
}
1214+
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
1215+
assert(_init_lock_offset != 0, "must be set");
1216+
java_class->obj_field_put(_init_lock_offset, init_lock);
1217+
}
1218+
11991219
objArrayOop java_lang_Class::signers(oop java_class) {
12001220
assert(_signers_offset != 0, "must be set");
12011221
return (objArrayOop)java_class->obj_field(_signers_offset);
@@ -1415,12 +1435,18 @@ void java_lang_Class::compute_offsets() {
14151435
InstanceKlass* k = vmClasses::Class_klass();
14161436
CLASS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
14171437

1438+
// Init lock is a C union with component_mirror. Only instanceKlass mirrors have
1439+
// init_lock and only ArrayKlass mirrors have component_mirror. Since both are oops
1440+
// GC treats them the same.
1441+
_init_lock_offset = _component_mirror_offset;
1442+
14181443
CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
14191444
}
14201445

14211446
#if INCLUDE_CDS
14221447
void java_lang_Class::serialize_offsets(SerializeClosure* f) {
14231448
f->do_bool(&_offsets_computed);
1449+
f->do_u4((u4*)&_init_lock_offset);
14241450

14251451
CLASS_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
14261452

src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2024, 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
@@ -226,6 +226,7 @@ class java_lang_Class : AllStatic {
226226
static int _static_oop_field_count_offset;
227227

228228
static int _protection_domain_offset;
229+
static int _init_lock_offset;
229230
static int _signers_offset;
230231
static int _class_loader_offset;
231232
static int _module_offset;
@@ -240,6 +241,7 @@ class java_lang_Class : AllStatic {
240241
static GrowableArray<Klass*>* _fixup_mirror_list;
241242
static GrowableArray<Klass*>* _fixup_module_field_list;
242243

244+
static void set_init_lock(oop java_class, oop init_lock);
243245
static void set_protection_domain(oop java_class, oop protection_domain);
244246
static void set_class_loader(oop java_class, oop class_loader);
245247
static void set_component_mirror(oop java_class, oop comp_mirror);
@@ -292,6 +294,10 @@ class java_lang_Class : AllStatic {
292294

293295
// Support for embedded per-class oops
294296
static oop protection_domain(oop java_class);
297+
static oop init_lock(oop java_class);
298+
static void clear_init_lock(oop java_class) {
299+
set_init_lock(java_class, nullptr);
300+
}
295301
static oop component_mirror(oop java_class);
296302
static objArrayOop signers(oop java_class);
297303
static void set_signers(oop java_class, objArrayOop signers);

src/hotspot/share/classfile/systemDictionary.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class SystemDictionary : AllStatic {
177177

178178
static void classes_do(MetaspaceClosure* it);
179179
// Iterate over all methods in all klasses
180-
180+
// Will not keep metadata alive. See ClassLoaderDataGraph::methods_do.
181181
static void methods_do(void f(Method*));
182182

183183
// Garbage collection support

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ class SerializeClosure;
557557
template(bool_array_signature, "[Z") \
558558
template(byte_array_signature, "[B") \
559559
template(char_array_signature, "[C") \
560+
template(int_array_signature, "[I") \
560561
template(runnable_signature, "Ljava/lang/Runnable;") \
561562
template(continuation_signature, "Ljdk/internal/vm/Continuation;") \
562563
template(continuationscope_signature, "Ljdk/internal/vm/ContinuationScope;") \

src/hotspot/share/gc/shared/barrierSetNMethod.cpp

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,9 @@ int BarrierSetNMethod::nmethod_stub_entry_barrier(address* return_address_ptr) {
172172
nmethod* nm = cb->as_nmethod();
173173
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
174174

175-
if (!bs_nm->is_armed(nm)) {
176-
return 0;
177-
}
178-
179-
assert(!nm->is_osr_method(), "Should not reach here");
180175
// Called upon first entry after being armed
181176
bool may_enter = bs_nm->nmethod_entry_barrier(nm);
177+
assert(!nm->is_osr_method() || may_enter, "OSR nmethods should always be entrant after migration");
182178

183179
// In case a concurrent thread disarmed the nmethod, we need to ensure the new instructions
184180
// are made visible, by using a cross modify fence. Note that this is synchronous cross modifying
@@ -188,11 +184,11 @@ int BarrierSetNMethod::nmethod_stub_entry_barrier(address* return_address_ptr) {
188184
// it can be made conditional on the nmethod_patching_type.
189185
OrderAccess::cross_modify_fence();
190186

191-
// Diagnostic option to force deoptimization 1 in 3 times. It is otherwise
187+
// Diagnostic option to force deoptimization 1 in 10 times. It is otherwise
192188
// a very rare event.
193-
if (DeoptimizeNMethodBarriersALot) {
189+
if (DeoptimizeNMethodBarriersALot && !nm->is_osr_method()) {
194190
static volatile uint32_t counter=0;
195-
if (Atomic::add(&counter, 1u) % 3 == 0) {
191+
if (Atomic::add(&counter, 1u) % 10 == 0) {
196192
may_enter = false;
197193
}
198194
}
@@ -205,15 +201,6 @@ int BarrierSetNMethod::nmethod_stub_entry_barrier(address* return_address_ptr) {
205201
}
206202

207203
bool BarrierSetNMethod::nmethod_osr_entry_barrier(nmethod* nm) {
208-
// This check depends on the invariant that all nmethods that are deoptimized / made not entrant
209-
// are NOT disarmed.
210-
// This invariant is important because a method can be deoptimized after the method have been
211-
// resolved / looked up by OSR by another thread. By not deoptimizing them we guarantee that
212-
// a deoptimized method will always hit the barrier and come to the same conclusion - deoptimize
213-
if (!is_armed(nm)) {
214-
return true;
215-
}
216-
217204
assert(nm->is_osr_method(), "Should not reach here");
218205
log_trace(nmethod, barrier)("Running osr nmethod entry barrier: " PTR_FORMAT, p2i(nm));
219206
bool result = nmethod_entry_barrier(nm);

src/hotspot/share/interpreter/linkResolver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1810,7 +1810,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan
18101810
// the interpreter or runtime performs a serialized check of
18111811
// the relevant ResolvedIndyEntry::method field. This is done by the caller
18121812
// of this method, via CPC::set_dynamic_call, which uses
1813-
// a lock to do the final serialization of updates
1813+
// an ObjectLocker to do the final serialization of updates
18141814
// to ResolvedIndyEntry state, including method.
18151815

18161816
// Log dynamic info to CDS classlist.

src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ jlong JfrChunk::nanos_now() {
4747
const jlong now = seconds * 1000000000 + nanos;
4848
if (now > last) {
4949
last = now;
50-
} else {
51-
++last;
5250
}
5351
return last;
5452
}

0 commit comments

Comments
 (0)