8240205: Avoid PackageEntry lookup when loading shared classes
Do the PackageEntry lookup at one place and then pass it along to the subsequently called functions which need it. Reviewed-by: redestad, lfoltan
This commit is contained in:
parent
965404dd98
commit
512644de06
@ -5711,7 +5711,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
|
||||
oop cl = ik->class_loader();
|
||||
Handle clh = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(cl));
|
||||
ClassLoaderData* cld = ClassLoaderData::class_loader_data_or_null(clh());
|
||||
ik->set_package(cld, CHECK);
|
||||
ik->set_package(cld, NULL, CHECK);
|
||||
|
||||
const Array<Method*>* const methods = ik->methods();
|
||||
assert(methods != NULL, "invariant");
|
||||
|
@ -1157,10 +1157,11 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
||||
// Load a class for boot loader from the shared spaces. This also
|
||||
// forces the super class and all interfaces to be loaded.
|
||||
InstanceKlass* SystemDictionary::load_shared_boot_class(Symbol* class_name,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS) {
|
||||
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
|
||||
if (ik != NULL && ik->is_shared_boot_class()) {
|
||||
return load_shared_class(ik, Handle(), Handle(), NULL, THREAD);
|
||||
return load_shared_class(ik, Handle(), Handle(), NULL, pkg_entry, THREAD);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1173,6 +1174,7 @@ InstanceKlass* SystemDictionary::load_shared_boot_class(Symbol* class_name,
|
||||
// be defined in an unnamed module.
|
||||
bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
InstanceKlass* ik,
|
||||
PackageEntry* pkg_entry,
|
||||
Handle class_loader, TRAPS) {
|
||||
assert(!ModuleEntryTable::javabase_moduleEntry()->is_patched(),
|
||||
"Cannot use sharing if java.base is patched");
|
||||
@ -1197,12 +1199,11 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
return true;
|
||||
}
|
||||
// Get the pkg_entry from the classloader
|
||||
PackageEntry* pkg_entry = NULL;
|
||||
ModuleEntry* mod_entry = NULL;
|
||||
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
|
||||
TempNewSymbol pkg_name = pkg_entry != NULL ? pkg_entry->name() :
|
||||
ClassLoader::package_from_class_name(class_name);
|
||||
if (pkg_name != NULL) {
|
||||
if (loader_data != NULL) {
|
||||
pkg_entry = loader_data->packages()->lookup_only(pkg_name);
|
||||
if (pkg_entry != NULL) {
|
||||
mod_entry = pkg_entry->module();
|
||||
// If the archived class is from a module that has been patched at runtime,
|
||||
@ -1299,13 +1300,14 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
const ClassFileStream *cfs,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS) {
|
||||
assert(ik != NULL, "sanity");
|
||||
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);
|
||||
class_name, ik, pkg_entry, class_loader, CHECK_NULL);
|
||||
if (!visible) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1341,7 +1343,7 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
|
||||
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->restore_unshareable_info(loader_data, protection_domain, pkg_entry, CHECK_NULL);
|
||||
}
|
||||
|
||||
load_shared_class_misc(ik, loader_data, CHECK_NULL);
|
||||
@ -1408,7 +1410,7 @@ void SystemDictionary::quick_resolve(InstanceKlass* klass, ClassLoaderData* load
|
||||
}
|
||||
}
|
||||
|
||||
klass->restore_unshareable_info(loader_data, domain, THREAD);
|
||||
klass->restore_unshareable_info(loader_data, domain, NULL, THREAD);
|
||||
load_shared_class_misc(klass, loader_data, CHECK);
|
||||
Dictionary* dictionary = loader_data->dictionary();
|
||||
unsigned int hash = dictionary->compute_hash(klass->name());
|
||||
@ -1488,7 +1490,7 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
|
||||
{
|
||||
#if INCLUDE_CDS
|
||||
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
|
||||
k = load_shared_boot_class(class_name, THREAD);
|
||||
k = load_shared_boot_class(class_name, pkg_entry, THREAD);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -592,6 +592,7 @@ protected:
|
||||
Handle class_loader,
|
||||
InstanceKlass* k, TRAPS);
|
||||
static bool is_shared_class_visible(Symbol* class_name, InstanceKlass* ik,
|
||||
PackageEntry* pkg_entry,
|
||||
Handle class_loader, TRAPS);
|
||||
static bool check_shared_class_super_type(InstanceKlass* child, InstanceKlass* super,
|
||||
Handle class_loader, Handle protection_domain,
|
||||
@ -602,10 +603,12 @@ protected:
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
const ClassFileStream *cfs,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS);
|
||||
// Second part of load_shared_class
|
||||
static void load_shared_class_misc(InstanceKlass* ik, ClassLoaderData* loader_data, TRAPS) NOT_CDS_RETURN;
|
||||
static InstanceKlass* load_shared_boot_class(Symbol* class_name,
|
||||
PackageEntry* pkg_entry,
|
||||
TRAPS);
|
||||
static InstanceKlass* load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
|
||||
static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
|
||||
|
@ -585,7 +585,7 @@ Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader,
|
||||
// Initializes the java.lang.Package and java.security.ProtectionDomain objects associated with
|
||||
// the given InstanceKlass.
|
||||
// Returns the ProtectionDomain for the InstanceKlass.
|
||||
Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS) {
|
||||
Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, PackageEntry* pkg_entry, TRAPS) {
|
||||
Handle pd;
|
||||
|
||||
if (ik != NULL) {
|
||||
@ -598,18 +598,10 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
|
||||
// For shared app/platform classes originated from the run-time image:
|
||||
// The ProtectionDomains are cached in the corresponding ModuleEntries
|
||||
// for fast access by the VM.
|
||||
ResourceMark rm;
|
||||
ClassLoaderData *loader_data =
|
||||
ClassLoaderData::class_loader_data(class_loader());
|
||||
PackageEntryTable* pkgEntryTable = loader_data->packages();
|
||||
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
|
||||
if (pkg_name != NULL) {
|
||||
PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name);
|
||||
if (pkg_entry != NULL) {
|
||||
ModuleEntry* mod_entry = pkg_entry->module();
|
||||
pd = get_shared_protection_domain(class_loader, mod_entry, THREAD);
|
||||
define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd));
|
||||
}
|
||||
if (pkg_entry != NULL) {
|
||||
ModuleEntry* mod_entry = pkg_entry->module();
|
||||
pd = get_shared_protection_domain(class_loader, mod_entry, THREAD);
|
||||
define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd));
|
||||
}
|
||||
} else {
|
||||
// For shared app/platform classes originated from JAR files on the class path:
|
||||
@ -849,6 +841,15 @@ InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
|
||||
return k;
|
||||
}
|
||||
|
||||
PackageEntry* SystemDictionaryShared::get_package_entry_from_class_name(Handle class_loader, Symbol* class_name) {
|
||||
PackageEntry* pkg_entry = NULL;
|
||||
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
|
||||
if (pkg_name != NULL) {
|
||||
pkg_entry = class_loader_data(class_loader)->packages()->lookup_only(pkg_name);
|
||||
}
|
||||
return pkg_entry;
|
||||
}
|
||||
|
||||
InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
|
||||
Symbol* class_name, Handle class_loader, TRAPS) {
|
||||
assert(UseSharedSpaces, "must be");
|
||||
@ -859,9 +860,10 @@ InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
|
||||
SystemDictionary::is_system_class_loader(class_loader())) ||
|
||||
(ik->is_shared_platform_class() &&
|
||||
SystemDictionary::is_platform_class_loader(class_loader()))) {
|
||||
PackageEntry* pkg_entry = get_package_entry_from_class_name(class_loader, class_name);
|
||||
Handle protection_domain =
|
||||
SystemDictionaryShared::init_security_info(class_loader, ik, CHECK_NULL);
|
||||
return load_shared_class(ik, class_loader, protection_domain, NULL, THREAD);
|
||||
SystemDictionaryShared::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);
|
||||
return load_shared_class(ik, class_loader, protection_domain, NULL, pkg_entry, THREAD);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -960,9 +962,12 @@ InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread(
|
||||
// No need to lock, as <ik> can be held only by a single thread.
|
||||
loader_data->add_class(ik);
|
||||
|
||||
// Get the package entry.
|
||||
PackageEntry* pkg_entry = get_package_entry_from_class_name(class_loader, ik->name());
|
||||
|
||||
// Load and check super/interfaces, restore unsharable info
|
||||
InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain,
|
||||
cfs, THREAD);
|
||||
cfs, pkg_entry, THREAD);
|
||||
if (shared_klass == NULL || HAS_PENDING_EXCEPTION) {
|
||||
// TODO: clean up <ik> so it can be used again
|
||||
return NULL;
|
||||
|
@ -132,6 +132,8 @@ private:
|
||||
TRAPS);
|
||||
static Handle get_package_name(Symbol* class_name, TRAPS);
|
||||
|
||||
static PackageEntry* get_package_entry_from_class_name(Handle class_loader, Symbol* class_name);
|
||||
|
||||
|
||||
// Package handling:
|
||||
//
|
||||
@ -180,7 +182,7 @@ private:
|
||||
TRAPS);
|
||||
static Handle get_shared_protection_domain(Handle class_loader,
|
||||
ModuleEntry* mod, TRAPS);
|
||||
static Handle init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS);
|
||||
static Handle init_security_info(Handle class_loader, InstanceKlass* ik, PackageEntry* pkg_entry, TRAPS);
|
||||
|
||||
static void atomic_set_array_index(objArrayOop array, int index, oop o) {
|
||||
// Benign race condition: array.obj_at(index) may already be filled in.
|
||||
|
@ -280,7 +280,11 @@ void initialize_basic_type_klass(Klass* k, TRAPS) {
|
||||
if (UseSharedSpaces) {
|
||||
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||
assert(k->super() == ok, "u3");
|
||||
k->restore_unshareable_info(loader_data, Handle(), CHECK);
|
||||
if (k->is_instance_klass()) {
|
||||
InstanceKlass::cast(k)->restore_unshareable_info(loader_data, Handle(), NULL, CHECK);
|
||||
} else {
|
||||
ArrayKlass::cast(k)->restore_unshareable_info(loader_data, Handle(), CHECK);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ class ArrayKlass: public Klass {
|
||||
// CDS support - remove and restore oops from metadata. Oops are not shared.
|
||||
virtual void remove_unshareable_info();
|
||||
virtual void remove_java_mirror();
|
||||
virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
|
||||
void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
|
||||
|
||||
// Printing
|
||||
void print_on(outputStream* st) const;
|
||||
|
@ -2433,12 +2433,13 @@ void InstanceKlass::remove_java_mirror() {
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
|
||||
void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain,
|
||||
PackageEntry* pkg_entry, TRAPS) {
|
||||
// SystemDictionary::add_to_hierarchy() sets the init_state to loaded
|
||||
// before the InstanceKlass is added to the SystemDictionary. Make
|
||||
// sure the current state is <loaded.
|
||||
assert(!is_loaded(), "invalid init state");
|
||||
set_package(loader_data, CHECK);
|
||||
set_package(loader_data, pkg_entry, CHECK);
|
||||
Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
|
||||
|
||||
Array<Method*>* methods = this->methods();
|
||||
@ -2462,7 +2463,7 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
|
||||
if (array_klasses() != NULL) {
|
||||
// Array classes have null protection domain.
|
||||
// --> see ArrayKlass::complete_create_array_klass()
|
||||
array_klasses()->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
|
||||
ArrayKlass::cast(array_klasses())->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
|
||||
}
|
||||
|
||||
// Initialize current biased locking state.
|
||||
@ -2657,23 +2658,22 @@ ModuleEntry* InstanceKlass::module() const {
|
||||
return class_loader_data()->unnamed_module();
|
||||
}
|
||||
|
||||
void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
|
||||
void InstanceKlass::set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS) {
|
||||
|
||||
// ensure java/ packages only loaded by boot or platform builtin loaders
|
||||
check_prohibited_package(name(), loader_data, CHECK);
|
||||
|
||||
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(name());
|
||||
TempNewSymbol pkg_name = pkg_entry != NULL ? pkg_entry->name() : ClassLoader::package_from_class_name(name());
|
||||
|
||||
if (pkg_name != NULL && loader_data != NULL) {
|
||||
|
||||
// Find in class loader's package entry table.
|
||||
_package_entry = loader_data->packages()->lookup_only(pkg_name);
|
||||
_package_entry = pkg_entry != NULL ? pkg_entry : loader_data->packages()->lookup_only(pkg_name);
|
||||
|
||||
// If the package name is not found in the loader's package
|
||||
// entry table, it is an indication that the package has not
|
||||
// been defined. Consider it defined within the unnamed module.
|
||||
if (_package_entry == NULL) {
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
if (!ModuleEntryTable::javabase_defined()) {
|
||||
// Before java.base is defined during bootstrapping, define all packages in
|
||||
@ -2689,6 +2689,7 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
|
||||
}
|
||||
|
||||
// A package should have been successfully created
|
||||
DEBUG_ONLY(ResourceMark rm(THREAD));
|
||||
assert(_package_entry != NULL, "Package entry for class %s not found, loader %s",
|
||||
name()->as_C_string(), loader_data->loader_name_and_id());
|
||||
}
|
||||
|
@ -511,7 +511,7 @@ public:
|
||||
ModuleEntry* module() const;
|
||||
bool in_unnamed_package() const { return (_package_entry == NULL); }
|
||||
void set_package(PackageEntry* p) { _package_entry = p; }
|
||||
void set_package(ClassLoaderData* loader_data, TRAPS);
|
||||
void set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS);
|
||||
bool is_same_class_package(const Klass* class2) const;
|
||||
bool is_same_class_package(oop other_class_loader, const Symbol* other_class_name) const;
|
||||
|
||||
@ -1327,7 +1327,7 @@ public:
|
||||
// CDS support - remove and restore oops from metadata. Oops are not shared.
|
||||
virtual void remove_unshareable_info();
|
||||
virtual void remove_java_mirror();
|
||||
virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
|
||||
void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS);
|
||||
|
||||
// jvm support
|
||||
jint compute_modifier_flags(TRAPS) const;
|
||||
|
@ -506,6 +506,7 @@ protected:
|
||||
void set_vtable_length(int len) { _vtable_len= len; }
|
||||
|
||||
vtableEntry* start_of_vtable() const;
|
||||
void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
|
||||
public:
|
||||
Method* method_at_vtable(int index);
|
||||
|
||||
@ -517,7 +518,6 @@ protected:
|
||||
// CDS support - remove and restore oops from metadata. Oops are not shared.
|
||||
virtual void remove_unshareable_info();
|
||||
virtual void remove_java_mirror();
|
||||
virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
|
||||
|
||||
bool is_unshareable_info_restored() const {
|
||||
assert(is_shared(), "use this for shared classes only");
|
||||
|
Loading…
x
Reference in New Issue
Block a user