Skip to content

Commit cf4a496

Browse files
committedJun 16, 2022
8288064: Class initialization locking
Reviewed-by: rehn, vlivanov
1 parent 3d12c02 commit cf4a496

File tree

14 files changed

+140
-172
lines changed

14 files changed

+140
-172
lines changed
 

‎src/hotspot/share/classfile/javaClasses.cpp

-28
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,6 @@ int java_lang_Class::_class_loader_offset;
792792
int java_lang_Class::_module_offset;
793793
int java_lang_Class::_protection_domain_offset;
794794
int java_lang_Class::_component_mirror_offset;
795-
int java_lang_Class::_init_lock_offset;
796795
int java_lang_Class::_signers_offset;
797796
int java_lang_Class::_name_offset;
798797
int java_lang_Class::_source_file_offset;
@@ -926,12 +925,6 @@ void java_lang_Class::initialize_mirror_fields(Klass* k,
926925
Handle protection_domain,
927926
Handle classData,
928927
TRAPS) {
929-
// Allocate a simple java object for a lock.
930-
// This needs to be a java object because during class initialization
931-
// it can be held across a java call.
932-
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
933-
set_init_lock(mirror(), r);
934-
935928
// Set protection domain also
936929
set_protection_domain(mirror(), protection_domain());
937930

@@ -1270,8 +1263,6 @@ oop java_lang_Class::process_archived_mirror(Klass* k, oop mirror,
12701263
// Reset local static fields in the mirror
12711264
InstanceKlass::cast(k)->do_local_static_fields(&reset);
12721265

1273-
set_init_lock(archived_mirror, NULL);
1274-
12751266
set_protection_domain(archived_mirror, NULL);
12761267
set_signers(archived_mirror, NULL);
12771268
set_source_file(archived_mirror, NULL);
@@ -1353,10 +1344,6 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
13531344
if (!k->is_array_klass()) {
13541345
// - local static final fields with initial values were initialized at dump time
13551346

1356-
// create the init_lock
1357-
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
1358-
set_init_lock(mirror(), r);
1359-
13601347
if (protection_domain.not_null()) {
13611348
set_protection_domain(mirror(), protection_domain());
13621349
}
@@ -1421,15 +1408,6 @@ oop java_lang_Class::component_mirror(oop java_class) {
14211408
return java_class->obj_field(_component_mirror_offset);
14221409
}
14231410

1424-
oop java_lang_Class::init_lock(oop java_class) {
1425-
assert(_init_lock_offset != 0, "must be set");
1426-
return java_class->obj_field(_init_lock_offset);
1427-
}
1428-
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
1429-
assert(_init_lock_offset != 0, "must be set");
1430-
java_class->obj_field_put(_init_lock_offset, init_lock);
1431-
}
1432-
14331411
objArrayOop java_lang_Class::signers(oop java_class) {
14341412
assert(_signers_offset != 0, "must be set");
14351413
return (objArrayOop)java_class->obj_field(_signers_offset);
@@ -1641,18 +1619,12 @@ void java_lang_Class::compute_offsets() {
16411619
InstanceKlass* k = vmClasses::Class_klass();
16421620
CLASS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
16431621

1644-
// Init lock is a C union with component_mirror. Only instanceKlass mirrors have
1645-
// init_lock and only ArrayKlass mirrors have component_mirror. Since both are oops
1646-
// GC treats them the same.
1647-
_init_lock_offset = _component_mirror_offset;
1648-
16491622
CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
16501623
}
16511624

16521625
#if INCLUDE_CDS
16531626
void java_lang_Class::serialize_offsets(SerializeClosure* f) {
16541627
f->do_bool(&_offsets_computed);
1655-
f->do_u4((u4*)&_init_lock_offset);
16561628

16571629
CLASS_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
16581630

‎src/hotspot/share/classfile/javaClasses.hpp

-6
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ class java_lang_Class : AllStatic {
285285
static int _static_oop_field_count_offset;
286286

287287
static int _protection_domain_offset;
288-
static int _init_lock_offset;
289288
static int _signers_offset;
290289
static int _class_loader_offset;
291290
static int _module_offset;
@@ -300,7 +299,6 @@ class java_lang_Class : AllStatic {
300299
static GrowableArray<Klass*>* _fixup_mirror_list;
301300
static GrowableArray<Klass*>* _fixup_module_field_list;
302301

303-
static void set_init_lock(oop java_class, oop init_lock);
304302
static void set_protection_domain(oop java_class, oop protection_domain);
305303
static void set_class_loader(oop java_class, oop class_loader);
306304
static void set_component_mirror(oop java_class, oop comp_mirror);
@@ -356,10 +354,6 @@ class java_lang_Class : AllStatic {
356354

357355
// Support for embedded per-class oops
358356
static oop protection_domain(oop java_class);
359-
static oop init_lock(oop java_class);
360-
static void clear_init_lock(oop java_class) {
361-
set_init_lock(java_class, NULL);
362-
}
363357
static oop component_mirror(oop java_class);
364358
static objArrayOop signers(oop java_class);
365359
static void set_signers(oop java_class, objArrayOop signers);

‎src/hotspot/share/interpreter/linkResolver.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1774,7 +1774,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan
17741774
// the interpreter or runtime performs a serialized check of
17751775
// the relevant CPCE::f1 field. This is done by the caller
17761776
// of this method, via CPCE::set_dynamic_call, which uses
1777-
// an ObjectLocker to do the final serialization of updates
1777+
// a lock to do the final serialization of updates
17781778
// to CPCE state, including f1.
17791779

17801780
// Log dynamic info to CDS classlist.

‎src/hotspot/share/jvmci/vmStructs_jvmci.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
\
157157
nonstatic_field(InstanceKlass, _fields, Array<u2>*) \
158158
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
159-
nonstatic_field(InstanceKlass, _init_state, u1) \
159+
nonstatic_field(InstanceKlass, _init_state, InstanceKlass::ClassState) \
160160
nonstatic_field(InstanceKlass, _init_thread, Thread*) \
161161
nonstatic_field(InstanceKlass, _misc_flags, u2) \
162162
nonstatic_field(InstanceKlass, _annotations, Annotations*) \

‎src/hotspot/share/oops/cpCache.cpp

+5-17
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
266266
}
267267
if (invoke_code == Bytecodes::_invokestatic) {
268268
assert(method->method_holder()->is_initialized() ||
269-
method->method_holder()->is_reentrant_initialization(Thread::current()),
269+
method->method_holder()->is_init_thread(Thread::current()),
270270
"invalid class initialization state for invoke_static");
271271

272272
if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
@@ -373,15 +373,9 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
373373
// A losing writer waits on the lock until the winner writes f1 and leaves
374374
// the lock, so that when the losing writer returns, he can use the linked
375375
// cache entry.
376+
// Lock fields to write
377+
MutexLocker ml(cpool->pool_holder()->init_monitor());
376378

377-
JavaThread* current = JavaThread::current();
378-
objArrayHandle resolved_references(current, cpool->resolved_references());
379-
// Use the resolved_references() lock for this cpCache entry.
380-
// resolved_references are created for all classes with Invokedynamic, MethodHandle
381-
// or MethodType constant pool cache entries.
382-
assert(resolved_references() != NULL,
383-
"a resolved_references array should have been created for this class");
384-
ObjectLocker ol(resolved_references, current);
385379
if (!is_f1_null()) {
386380
return;
387381
}
@@ -453,6 +447,7 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
453447
// Store appendix, if any.
454448
if (has_appendix) {
455449
const int appendix_index = f2_as_index();
450+
objArrayOop resolved_references = cpool->resolved_references();
456451
assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
457452
assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
458453
resolved_references->obj_at_put(appendix_index, appendix());
@@ -480,14 +475,7 @@ bool ConstantPoolCacheEntry::save_and_throw_indy_exc(
480475
assert(PENDING_EXCEPTION->is_a(vmClasses::LinkageError_klass()),
481476
"No LinkageError exception");
482477

483-
// Use the resolved_references() lock for this cpCache entry.
484-
// resolved_references are created for all classes with Invokedynamic, MethodHandle
485-
// or MethodType constant pool cache entries.
486-
JavaThread* current = THREAD;
487-
objArrayHandle resolved_references(current, cpool->resolved_references());
488-
assert(resolved_references() != NULL,
489-
"a resolved_references array should have been created for this class");
490-
ObjectLocker ol(resolved_references, current);
478+
MutexLocker ml(THREAD, cpool->pool_holder()->init_monitor());
491479

492480
// if f1 is not null or the indy_resolution_failed flag is set then another
493481
// thread either succeeded in resolving the method or got a LinkageError

0 commit comments

Comments
 (0)
Please sign in to comment.