Skip to content

Commit

Permalink
8231275: Remove null check in the beginning of SystemDictionary::load…
Browse files Browse the repository at this point in the history
…_shared_class()

Reviewed-by: ccheung, coleenp
  • Loading branch information
iklam committed Sep 23, 2019
1 parent 9c92ecb commit b18626a
Showing 1 changed file with 92 additions and 93 deletions.
185 changes: 92 additions & 93 deletions src/hotspot/share/classfile/systemDictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
} else {
assert(s->is_shared(), "must be");
}
}

// 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");
}
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;
}
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.
// 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.
// 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);
}
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);
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);
}
// 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();
}
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 */);
// 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);
}
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
Expand Down

0 comments on commit b18626a

Please sign in to comment.