8231275: Remove null check in the beginning of SystemDictionary::load_shared_class()

Reviewed-by: ccheung, coleenp
This commit is contained in:
Ioi Lam 2019-09-22 17:17:58 -07:00
parent 9c92ecba04
commit b18626ae7a

View file

@ -1268,117 +1268,116 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
Handle protection_domain,
const ClassFileStream *cfs,
TRAPS) {
assert(ik != NULL, "sanity");
assert(!ik->is_unshareable_info_restored(), "shared class can be loaded only once");
Symbol* class_name = ik->name();
if (ik != NULL) {
assert(!ik->is_unshareable_info_restored(), "shared class can be loaded only once");
Symbol* class_name = ik->name();
bool visible = is_shared_class_visible(
class_name, ik, class_loader, CHECK_NULL);
if (!visible) {
return NULL;
}
bool visible = is_shared_class_visible(
class_name, ik, class_loader, CHECK_NULL);
if (!visible) {
// Resolve the superclass and interfaces. They must be the same
// as in dump time, because the layout of <ik> depends on
// the specific layout of ik->super() and ik->local_interfaces().
//
// If unexpected superclass or interfaces are found, we cannot
// load <ik> from the shared archive.
if (ik->super() != NULL) {
Symbol* cn = ik->super()->name();
Klass *s = resolve_super_or_fail(class_name, cn,
class_loader, protection_domain, true, CHECK_NULL);
if (s != ik->super()) {
// The dynamically resolved super class is not the same as the one we used during dump time,
// so we cannot use ik.
return NULL;
}
// Resolve the superclass and interfaces. They must be the same
// as in dump time, because the layout of <ik> depends on
// the specific layout of ik->super() and ik->local_interfaces().
//
// If unexpected superclass or interfaces are found, we cannot
// load <ik> from the shared archive.
if (ik->super() != NULL) {
Symbol* cn = ik->super()->name();
Klass *s = resolve_super_or_fail(class_name, cn,
class_loader, protection_domain, true, CHECK_NULL);
if (s != ik->super()) {
// The dynamically resolved super class is not the same as the one we used during dump time,
// so we cannot use ik.
return NULL;
} else {
assert(s->is_shared(), "must be");
}
}
Array<InstanceKlass*>* interfaces = ik->local_interfaces();
int num_interfaces = interfaces->length();
for (int index = 0; index < num_interfaces; index++) {
InstanceKlass* k = interfaces->at(index);
Symbol* name = k->name();
Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_NULL);
if (k != i) {
// The dynamically resolved interface class is not the same as the one we used during dump time,
// so we cannot use ik.
return NULL;
} else {
assert(i->is_shared(), "must be");
}
}
InstanceKlass* new_ik = KlassFactory::check_shared_class_file_load_hook(
ik, class_name, class_loader, protection_domain, cfs, CHECK_NULL);
if (new_ik != NULL) {
// The class is changed by CFLH. Return the new class. The shared class is
// not used.
return new_ik;
}
// Adjust methods to recover missing data. They need addresses for
// interpreter entry points and their default native method address
// must be reset.
// Updating methods must be done under a lock so multiple
// threads don't update these in parallel
//
// Shared classes are all currently loaded by either the bootstrap or
// internal parallel class loaders, so this will never cause a deadlock
// on a custom class loader lock.
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
{
HandleMark hm(THREAD);
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, true);
// prohibited package check assumes all classes loaded from archive call
// restore_unshareable_info which calls ik->set_package()
ik->restore_unshareable_info(loader_data, protection_domain, CHECK_NULL);
}
ik->print_class_load_logging(loader_data, NULL, NULL);
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (class_loader.is_null()) {
int path_index = ik->shared_classpath_index();
ResourceMark rm;
ClassLoader::add_package(ik->name()->as_C_string(), path_index, THREAD);
}
if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
// Only dump the classes that can be stored into CDS archive
if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
ResourceMark rm(THREAD);
classlist_file->print_cr("%s", ik->name()->as_C_string());
classlist_file->flush();
}
}
// notify a class loaded from shared object
ClassLoadingService::notify_class_loaded(ik, true /* shared class */);
ik->set_has_passed_fingerprint_check(false);
if (UseAOT && ik->supers_have_passed_fingerprint_checks()) {
uint64_t aot_fp = AOTLoader::get_saved_fingerprint(ik);
uint64_t cds_fp = ik->get_stored_fingerprint();
if (aot_fp != 0 && aot_fp == cds_fp) {
// This class matches with a class saved in an AOT library
ik->set_has_passed_fingerprint_check(true);
} else {
ResourceMark rm;
log_info(class, fingerprint)("%s : expected = " PTR64_FORMAT " actual = " PTR64_FORMAT, ik->external_name(), aot_fp, cds_fp);
}
} else {
assert(s->is_shared(), "must be");
}
}
Array<InstanceKlass*>* interfaces = ik->local_interfaces();
int num_interfaces = interfaces->length();
for (int index = 0; index < num_interfaces; index++) {
InstanceKlass* k = interfaces->at(index);
Symbol* name = k->name();
Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_NULL);
if (k != i) {
// The dynamically resolved interface class is not the same as the one we used during dump time,
// so we cannot use ik.
return NULL;
} else {
assert(i->is_shared(), "must be");
}
}
InstanceKlass* new_ik = KlassFactory::check_shared_class_file_load_hook(
ik, class_name, class_loader, protection_domain, cfs, CHECK_NULL);
if (new_ik != NULL) {
// The class is changed by CFLH. Return the new class. The shared class is
// not used.
return new_ik;
}
// Adjust methods to recover missing data. They need addresses for
// interpreter entry points and their default native method address
// must be reset.
// Updating methods must be done under a lock so multiple
// threads don't update these in parallel
//
// Shared classes are all currently loaded by either the bootstrap or
// internal parallel class loaders, so this will never cause a deadlock
// on a custom class loader lock.
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
{
HandleMark hm(THREAD);
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, true);
// prohibited package check assumes all classes loaded from archive call
// restore_unshareable_info which calls ik->set_package()
ik->restore_unshareable_info(loader_data, protection_domain, CHECK_NULL);
}
ik->print_class_load_logging(loader_data, NULL, NULL);
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (class_loader.is_null()) {
int path_index = ik->shared_classpath_index();
ResourceMark rm;
ClassLoader::add_package(ik->name()->as_C_string(), path_index, THREAD);
}
if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
// Only dump the classes that can be stored into CDS archive
if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
ResourceMark rm(THREAD);
classlist_file->print_cr("%s", ik->name()->as_C_string());
classlist_file->flush();
}
}
// notify a class loaded from shared object
ClassLoadingService::notify_class_loaded(ik, true /* shared class */);
ik->set_has_passed_fingerprint_check(false);
if (UseAOT && ik->supers_have_passed_fingerprint_checks()) {
uint64_t aot_fp = AOTLoader::get_saved_fingerprint(ik);
uint64_t cds_fp = ik->get_stored_fingerprint();
if (aot_fp != 0 && aot_fp == cds_fp) {
// This class matches with a class saved in an AOT library
ik->set_has_passed_fingerprint_check(true);
} else {
ResourceMark rm;
log_info(class, fingerprint)("%s : expected = " PTR64_FORMAT " actual = " PTR64_FORMAT, ik->external_name(), aot_fp, cds_fp);
}
}
return ik;
}
#endif // INCLUDE_CDS