8267954: Shared classes that failed to load should not be loaded again
Reviewed-by: iklam, ccheung
This commit is contained in:
parent
991ca14279
commit
7ff6e7b2b1
@ -956,19 +956,6 @@ InstanceKlass* SystemDictionary::resolve_from_stream(ClassFileStream* st,
|
||||
|
||||
|
||||
#if INCLUDE_CDS
|
||||
// Load a class for boot loader from the shared spaces. This also
|
||||
// forces the superclass and all interfaces to be loaded.
|
||||
InstanceKlass* SystemDictionary::load_shared_boot_class(Symbol* class_name,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS) {
|
||||
assert(UseSharedSpaces, "Sanity check");
|
||||
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
|
||||
if (ik != NULL && ik->is_shared_boot_class()) {
|
||||
return load_shared_class(ik, Handle(), Handle(), NULL, pkg_entry, THREAD);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if a shared class can be loaded by the specific classloader.
|
||||
bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
InstanceKlass* ik,
|
||||
@ -1289,7 +1276,11 @@ InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Ha
|
||||
if (UseSharedSpaces)
|
||||
{
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
|
||||
k = load_shared_boot_class(class_name, pkg_entry, THREAD);
|
||||
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
|
||||
if (ik != NULL && ik->is_shared_boot_class() && !ik->shared_loading_failed()) {
|
||||
SharedClassLoadingMark slm(THREAD, ik);
|
||||
k = load_shared_class(ik, class_loader, Handle(), NULL, pkg_entry, CHECK_NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1301,6 +1292,7 @@ InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Ha
|
||||
|
||||
// find_or_define_instance_class may return a different InstanceKlass
|
||||
if (k != NULL) {
|
||||
CDS_ONLY(SharedClassLoadingMark slm(THREAD, k);)
|
||||
k = find_or_define_instance_class(class_name, class_loader, k, CHECK_NULL);
|
||||
}
|
||||
return k;
|
||||
|
@ -376,9 +376,6 @@ protected:
|
||||
const ClassFileStream *cfs,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS);
|
||||
static InstanceKlass* load_shared_boot_class(Symbol* class_name,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS);
|
||||
static Handle get_loader_lock_or_null(Handle class_loader);
|
||||
static InstanceKlass* find_or_define_instance_class(Symbol* class_name,
|
||||
Handle class_loader,
|
||||
|
@ -1018,6 +1018,7 @@ InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
|
||||
|
||||
k = load_shared_class_for_builtin_loader(name, class_loader, THREAD);
|
||||
if (k != NULL) {
|
||||
SharedClassLoadingMark slm(THREAD, k);
|
||||
k = find_or_define_instance_class(name, class_loader, k, CHECK_NULL);
|
||||
}
|
||||
}
|
||||
@ -1047,11 +1048,10 @@ InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
|
||||
assert(UseSharedSpaces, "must be");
|
||||
InstanceKlass* ik = find_builtin_class(class_name);
|
||||
|
||||
if (ik != NULL) {
|
||||
if ((ik->is_shared_app_class() &&
|
||||
SystemDictionary::is_system_class_loader(class_loader())) ||
|
||||
(ik->is_shared_platform_class() &&
|
||||
SystemDictionary::is_platform_class_loader(class_loader()))) {
|
||||
if (ik != NULL && !ik->shared_loading_failed()) {
|
||||
if ((SystemDictionary::is_system_class_loader(class_loader()) && ik->is_shared_app_class()) ||
|
||||
(SystemDictionary::is_platform_class_loader(class_loader()) && ik->is_shared_platform_class())) {
|
||||
SharedClassLoadingMark slm(THREAD, ik);
|
||||
PackageEntry* pkg_entry = get_package_entry_from_class(ik, class_loader);
|
||||
Handle protection_domain =
|
||||
SystemDictionaryShared::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);
|
||||
|
@ -112,6 +112,23 @@ class LambdaProxyClassDictionary;
|
||||
class RunTimeSharedClassInfo;
|
||||
class RunTimeSharedDictionary;
|
||||
|
||||
class SharedClassLoadingMark {
|
||||
private:
|
||||
Thread* THREAD;
|
||||
InstanceKlass* _klass;
|
||||
public:
|
||||
SharedClassLoadingMark(Thread* current, InstanceKlass* ik) : THREAD(current), _klass(ik) {}
|
||||
~SharedClassLoadingMark() {
|
||||
assert(THREAD != NULL, "Current thread is NULL");
|
||||
assert(_klass != NULL, "InstanceKlass is NULL");
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
if (_klass->is_shared()) {
|
||||
_klass->set_shared_loading_failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SystemDictionaryShared: public SystemDictionary {
|
||||
friend class ExcludeDumpTimeSharedClasses;
|
||||
public:
|
||||
|
@ -2496,6 +2496,7 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
|
||||
// before the InstanceKlass is added to the SystemDictionary. Make
|
||||
// sure the current state is <loaded.
|
||||
assert(!is_loaded(), "invalid init state");
|
||||
assert(!shared_loading_failed(), "Must not try to load failed class again");
|
||||
set_package(loader_data, pkg_entry, CHECK);
|
||||
Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
|
||||
|
||||
|
@ -207,29 +207,27 @@ class InstanceKlass: public Klass {
|
||||
// Number of heapOopSize words used by non-static fields in this klass
|
||||
// (including inherited fields but after header_size()).
|
||||
int _nonstatic_field_size;
|
||||
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
|
||||
|
||||
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
|
||||
int _itable_len; // length of Java itable (in words)
|
||||
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
|
||||
int _nonstatic_oop_map_size; // size in words of nonstatic oop map blocks
|
||||
int _itable_len; // length of Java itable (in words)
|
||||
|
||||
// The NestHost attribute. The class info index for the class
|
||||
// that is the nest-host of this class. This data has not been validated.
|
||||
u2 _nest_host_index;
|
||||
u2 _this_class_index; // constant pool entry
|
||||
u2 _this_class_index; // constant pool entry
|
||||
u2 _static_oop_field_count; // number of static oop fields in this klass
|
||||
u2 _java_fields_count; // The number of declared Java fields
|
||||
|
||||
u2 _static_oop_field_count;// number of static oop fields in this klass
|
||||
u2 _java_fields_count; // The number of declared Java fields
|
||||
|
||||
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
|
||||
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
|
||||
|
||||
// _is_marked_dependent can be set concurrently, thus cannot be part of the
|
||||
// _misc_flags.
|
||||
bool _is_marked_dependent; // used for marking during flushing and deoptimization
|
||||
bool _is_marked_dependent; // used for marking during flushing and deoptimization
|
||||
|
||||
// Class states are defined as ClassState (see above).
|
||||
// Place the _init_state here to utilize the unused 2-byte after
|
||||
// _idnum_allocated_count.
|
||||
u1 _init_state; // state of class
|
||||
u1 _init_state; // state of class
|
||||
|
||||
// This can be used to quickly discriminate among the four kinds of
|
||||
// InstanceKlass. This should be an enum (?)
|
||||
@ -250,7 +248,7 @@ class InstanceKlass: public Klass {
|
||||
_misc_has_nonstatic_concrete_methods = 1 << 5, // class/superclass/implemented interfaces has non-static, concrete methods
|
||||
_misc_declares_nonstatic_concrete_methods = 1 << 6, // directly declares non-static, concrete methods
|
||||
_misc_has_been_redefined = 1 << 7, // class has been redefined
|
||||
_unused = 1 << 8, //
|
||||
_misc_shared_loading_failed = 1 << 8, // class has been loaded from shared archive
|
||||
_misc_is_scratch_class = 1 << 9, // class is the redefined scratch class
|
||||
_misc_is_shared_boot_class = 1 << 10, // defining class loader is boot class loader
|
||||
_misc_is_shared_platform_class = 1 << 11, // defining class loader is platform class loader
|
||||
@ -355,6 +353,18 @@ class InstanceKlass: public Klass {
|
||||
_misc_flags &= ~shared_loader_type_bits();
|
||||
}
|
||||
|
||||
bool shared_loading_failed() const {
|
||||
return (_misc_flags & _misc_shared_loading_failed) != 0;
|
||||
}
|
||||
|
||||
void set_shared_loading_failed() {
|
||||
_misc_flags |= _misc_shared_loading_failed;
|
||||
}
|
||||
|
||||
void clear_shared_loading_failed() {
|
||||
_misc_flags &= ~_misc_shared_loading_failed;
|
||||
}
|
||||
|
||||
void set_shared_class_loader_type(s2 loader_type);
|
||||
|
||||
void assign_class_loader_type();
|
||||
|
@ -29,8 +29,6 @@
|
||||
|
||||
compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 8268033 generic-x64
|
||||
|
||||
runtime/cds/appcds/dynamicArchive/TestDynamicDumpAtOom.java 8267954 linux-x64
|
||||
|
||||
vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all
|
||||
|
||||
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 windows-x64
|
||||
|
Loading…
Reference in New Issue
Block a user