Skip to content

Commit 7ff6e7b

Browse files
committed
8267954: Shared classes that failed to load should not be loaded again
Reviewed-by: iklam, ccheung
1 parent 991ca14 commit 7ff6e7b

File tree

7 files changed

+51
-36
lines changed

7 files changed

+51
-36
lines changed

src/hotspot/share/classfile/systemDictionary.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -956,19 +956,6 @@ InstanceKlass* SystemDictionary::resolve_from_stream(ClassFileStream* st,
956956

957957

958958
#if INCLUDE_CDS
959-
// Load a class for boot loader from the shared spaces. This also
960-
// forces the superclass and all interfaces to be loaded.
961-
InstanceKlass* SystemDictionary::load_shared_boot_class(Symbol* class_name,
962-
PackageEntry* pkg_entry,
963-
TRAPS) {
964-
assert(UseSharedSpaces, "Sanity check");
965-
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
966-
if (ik != NULL && ik->is_shared_boot_class()) {
967-
return load_shared_class(ik, Handle(), Handle(), NULL, pkg_entry, THREAD);
968-
}
969-
return NULL;
970-
}
971-
972959
// Check if a shared class can be loaded by the specific classloader.
973960
bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
974961
InstanceKlass* ik,
@@ -1289,7 +1276,11 @@ InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Ha
12891276
if (UseSharedSpaces)
12901277
{
12911278
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
1292-
k = load_shared_boot_class(class_name, pkg_entry, THREAD);
1279+
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
1280+
if (ik != NULL && ik->is_shared_boot_class() && !ik->shared_loading_failed()) {
1281+
SharedClassLoadingMark slm(THREAD, ik);
1282+
k = load_shared_class(ik, class_loader, Handle(), NULL, pkg_entry, CHECK_NULL);
1283+
}
12931284
}
12941285
#endif
12951286

@@ -1301,6 +1292,7 @@ InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Ha
13011292

13021293
// find_or_define_instance_class may return a different InstanceKlass
13031294
if (k != NULL) {
1295+
CDS_ONLY(SharedClassLoadingMark slm(THREAD, k);)
13041296
k = find_or_define_instance_class(class_name, class_loader, k, CHECK_NULL);
13051297
}
13061298
return k;

src/hotspot/share/classfile/systemDictionary.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,6 @@ class SystemDictionary : AllStatic {
376376
const ClassFileStream *cfs,
377377
PackageEntry* pkg_entry,
378378
TRAPS);
379-
static InstanceKlass* load_shared_boot_class(Symbol* class_name,
380-
PackageEntry* pkg_entry,
381-
TRAPS);
382379
static Handle get_loader_lock_or_null(Handle class_loader);
383380
static InstanceKlass* find_or_define_instance_class(Symbol* class_name,
384381
Handle class_loader,

src/hotspot/share/classfile/systemDictionaryShared.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,7 @@ InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
10181018

10191019
k = load_shared_class_for_builtin_loader(name, class_loader, THREAD);
10201020
if (k != NULL) {
1021+
SharedClassLoadingMark slm(THREAD, k);
10211022
k = find_or_define_instance_class(name, class_loader, k, CHECK_NULL);
10221023
}
10231024
}
@@ -1047,11 +1048,10 @@ InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
10471048
assert(UseSharedSpaces, "must be");
10481049
InstanceKlass* ik = find_builtin_class(class_name);
10491050

1050-
if (ik != NULL) {
1051-
if ((ik->is_shared_app_class() &&
1052-
SystemDictionary::is_system_class_loader(class_loader())) ||
1053-
(ik->is_shared_platform_class() &&
1054-
SystemDictionary::is_platform_class_loader(class_loader()))) {
1051+
if (ik != NULL && !ik->shared_loading_failed()) {
1052+
if ((SystemDictionary::is_system_class_loader(class_loader()) && ik->is_shared_app_class()) ||
1053+
(SystemDictionary::is_platform_class_loader(class_loader()) && ik->is_shared_platform_class())) {
1054+
SharedClassLoadingMark slm(THREAD, ik);
10551055
PackageEntry* pkg_entry = get_package_entry_from_class(ik, class_loader);
10561056
Handle protection_domain =
10571057
SystemDictionaryShared::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);

src/hotspot/share/classfile/systemDictionaryShared.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,23 @@ class LambdaProxyClassDictionary;
112112
class RunTimeSharedClassInfo;
113113
class RunTimeSharedDictionary;
114114

115+
class SharedClassLoadingMark {
116+
private:
117+
Thread* THREAD;
118+
InstanceKlass* _klass;
119+
public:
120+
SharedClassLoadingMark(Thread* current, InstanceKlass* ik) : THREAD(current), _klass(ik) {}
121+
~SharedClassLoadingMark() {
122+
assert(THREAD != NULL, "Current thread is NULL");
123+
assert(_klass != NULL, "InstanceKlass is NULL");
124+
if (HAS_PENDING_EXCEPTION) {
125+
if (_klass->is_shared()) {
126+
_klass->set_shared_loading_failed();
127+
}
128+
}
129+
}
130+
};
131+
115132
class SystemDictionaryShared: public SystemDictionary {
116133
friend class ExcludeDumpTimeSharedClasses;
117134
public:

src/hotspot/share/oops/instanceKlass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,7 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
24962496
// before the InstanceKlass is added to the SystemDictionary. Make
24972497
// sure the current state is <loaded.
24982498
assert(!is_loaded(), "invalid init state");
2499+
assert(!shared_loading_failed(), "Must not try to load failed class again");
24992500
set_package(loader_data, pkg_entry, CHECK);
25002501
Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
25012502

src/hotspot/share/oops/instanceKlass.hpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,29 +207,27 @@ class InstanceKlass: public Klass {
207207
// Number of heapOopSize words used by non-static fields in this klass
208208
// (including inherited fields but after header_size()).
209209
int _nonstatic_field_size;
210-
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
211-
212-
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
213-
int _itable_len; // length of Java itable (in words)
210+
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
211+
int _nonstatic_oop_map_size; // size in words of nonstatic oop map blocks
212+
int _itable_len; // length of Java itable (in words)
214213

215214
// The NestHost attribute. The class info index for the class
216215
// that is the nest-host of this class. This data has not been validated.
217216
u2 _nest_host_index;
218-
u2 _this_class_index; // constant pool entry
219-
220-
u2 _static_oop_field_count;// number of static oop fields in this klass
221-
u2 _java_fields_count; // The number of declared Java fields
217+
u2 _this_class_index; // constant pool entry
218+
u2 _static_oop_field_count; // number of static oop fields in this klass
219+
u2 _java_fields_count; // The number of declared Java fields
222220

223-
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
221+
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
224222

225223
// _is_marked_dependent can be set concurrently, thus cannot be part of the
226224
// _misc_flags.
227-
bool _is_marked_dependent; // used for marking during flushing and deoptimization
225+
bool _is_marked_dependent; // used for marking during flushing and deoptimization
228226

229227
// Class states are defined as ClassState (see above).
230228
// Place the _init_state here to utilize the unused 2-byte after
231229
// _idnum_allocated_count.
232-
u1 _init_state; // state of class
230+
u1 _init_state; // state of class
233231

234232
// This can be used to quickly discriminate among the four kinds of
235233
// InstanceKlass. This should be an enum (?)
@@ -250,7 +248,7 @@ class InstanceKlass: public Klass {
250248
_misc_has_nonstatic_concrete_methods = 1 << 5, // class/superclass/implemented interfaces has non-static, concrete methods
251249
_misc_declares_nonstatic_concrete_methods = 1 << 6, // directly declares non-static, concrete methods
252250
_misc_has_been_redefined = 1 << 7, // class has been redefined
253-
_unused = 1 << 8, //
251+
_misc_shared_loading_failed = 1 << 8, // class has been loaded from shared archive
254252
_misc_is_scratch_class = 1 << 9, // class is the redefined scratch class
255253
_misc_is_shared_boot_class = 1 << 10, // defining class loader is boot class loader
256254
_misc_is_shared_platform_class = 1 << 11, // defining class loader is platform class loader
@@ -355,6 +353,18 @@ class InstanceKlass: public Klass {
355353
_misc_flags &= ~shared_loader_type_bits();
356354
}
357355

356+
bool shared_loading_failed() const {
357+
return (_misc_flags & _misc_shared_loading_failed) != 0;
358+
}
359+
360+
void set_shared_loading_failed() {
361+
_misc_flags |= _misc_shared_loading_failed;
362+
}
363+
364+
void clear_shared_loading_failed() {
365+
_misc_flags &= ~_misc_shared_loading_failed;
366+
}
367+
358368
void set_shared_class_loader_type(s2 loader_type);
359369

360370
void assign_class_loader_type();

test/hotspot/jtreg/ProblemList-Xcomp.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929

3030
compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 8268033 generic-x64
3131

32-
runtime/cds/appcds/dynamicArchive/TestDynamicDumpAtOom.java 8267954 linux-x64
33-
3432
vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all
3533

3634
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 windows-x64

0 commit comments

Comments
 (0)