8298468: Clean up class_loader parameters

Reviewed-by: dholmes, iklam
This commit is contained in:
Coleen Phillimore 2022-12-15 19:54:25 +00:00
parent 4b313b51b1
commit 10737e168c
5 changed files with 76 additions and 92 deletions

View File

@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "cds/cdsProtectionDomain.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/moduleEntry.hpp"
@ -125,7 +126,7 @@ PackageEntry* CDSProtectionDomain::get_package_entry_from_class(InstanceKlass* i
}
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(ik->name());
if (pkg_name != NULL) {
pkg_entry = SystemDictionaryShared::class_loader_data(class_loader)->packages()->lookup_only(pkg_name);
pkg_entry = ClassLoaderData::class_loader_data(class_loader())->packages()->lookup_only(pkg_name);
} else {
pkg_entry = NULL;
}

View File

@ -47,11 +47,11 @@ class LoaderConstraint : public CHeapObj<mtClass> {
// not class loaders.
GrowableArray<ClassLoaderData*>* _loaders; // initiating loaders
public:
LoaderConstraint(InstanceKlass* klass, oop class_loader1, oop class_loader2) :
LoaderConstraint(InstanceKlass* klass, ClassLoaderData* loader1, ClassLoaderData* loader2) :
_klass(klass) {
_loaders = new (mtClass) GrowableArray<ClassLoaderData*>(10, mtClass);
add_loader(class_loader1);
add_loader(class_loader2);
add_loader_data(loader1);
add_loader_data(loader2);
}
LoaderConstraint(const LoaderConstraint& src) = delete;
LoaderConstraint& operator=(const LoaderConstraint&) = delete;
@ -61,7 +61,7 @@ class LoaderConstraint : public CHeapObj<mtClass> {
InstanceKlass* klass() const { return _klass; }
void set_klass(InstanceKlass* k) { _klass = k; }
void extend_loader_constraint(Symbol* class_name, Handle loader, InstanceKlass* klass);
void extend_loader_constraint(Symbol* class_name, ClassLoaderData* loader, InstanceKlass* klass);
int num_loaders() const { return _loaders->length(); }
ClassLoaderData* loader_data(int i) { return _loaders->at(i); }
@ -71,11 +71,6 @@ class LoaderConstraint : public CHeapObj<mtClass> {
assert(_loaders->at(n)->is_unloading(), "should be unloading");
_loaders->remove_at(n);
}
// convenience
void add_loader(oop p) {
_loaders->push(ClassLoaderData::class_loader_data(p));
}
};
// For this class name, these are the set of LoaderConstraints for classes loaded with this name.
@ -114,15 +109,15 @@ class ConstraintSet { // copied into hashtable as
ResourceHashtable<SymbolHandle, ConstraintSet, 107, AnyObj::C_HEAP, mtClass, SymbolHandle::compute_hash> _loader_constraint_table;
void LoaderConstraint::extend_loader_constraint(Symbol* class_name,
Handle loader,
ClassLoaderData* loader,
InstanceKlass* klass) {
add_loader(loader());
add_loader_data(loader);
LogTarget(Info, class, loader, constraints) lt;
if (lt.is_enabled()) {
ResourceMark rm;
lt.print("extending constraint for name %s by adding loader: %s %s",
class_name->as_C_string(),
ClassLoaderData::class_loader_data(loader())->loader_name_and_id(),
loader->loader_name_and_id(),
_klass == NULL ? " and setting class object" : "");
}
if (_klass == NULL) {
@ -137,7 +132,7 @@ void LoaderConstraint::extend_loader_constraint(Symbol* class_name,
// entries in the table could be being dynamically resized.
LoaderConstraint* LoaderConstraintTable::find_loader_constraint(
Symbol* name, Handle loader) {
Symbol* name, ClassLoaderData* loader_data) {
assert_lock_strong(SystemDictionary_lock);
ConstraintSet* set = _loader_constraint_table.get(name);
@ -145,8 +140,6 @@ LoaderConstraint* LoaderConstraintTable::find_loader_constraint(
return nullptr;
}
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
for (int i = 0; i < set->num_constraints(); i++) {
LoaderConstraint* p = set->constraint_at(i);
for (int i = p->num_loaders() - 1; i >= 0; i--) {
@ -162,9 +155,10 @@ LoaderConstraint* LoaderConstraintTable::find_loader_constraint(
}
// Either add it to an existing entry in the table or make a new one.
void LoaderConstraintTable::add_loader_constraint(Symbol* name, InstanceKlass* klass, oop class_loader1, oop class_loader2) {
void LoaderConstraintTable::add_loader_constraint(Symbol* name, InstanceKlass* klass,
ClassLoaderData* loader1, ClassLoaderData* loader2) {
assert_lock_strong(SystemDictionary_lock);
LoaderConstraint* constraint = new LoaderConstraint(klass, class_loader1, class_loader2);
LoaderConstraint* constraint = new LoaderConstraint(klass, loader1, loader2);
// The klass may be null if it hasn't been loaded yet, for instance while checking
// a parameter name to a method call. We impose this constraint that the
@ -256,22 +250,22 @@ void LoaderConstraintTable::purge_loader_constraints() {
}
void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
Handle class_loader1, Handle class_loader2) {
ClassLoaderData* loader1, ClassLoaderData* loader2) {
LogTarget(Info, class, loader, constraints) lt;
if (lt.is_enabled()) {
ResourceMark rm;
lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
" loader[1]: %s, Reason: %s",
class_name->as_C_string(),
ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id(),
loader1->loader_name_and_id(),
loader2->loader_name_and_id(),
reason);
}
}
bool LoaderConstraintTable::add_entry(Symbol* class_name,
InstanceKlass* klass1, Handle class_loader1,
InstanceKlass* klass2, Handle class_loader2) {
InstanceKlass* klass1, ClassLoaderData* loader1,
InstanceKlass* klass2, ClassLoaderData* loader2) {
LogTarget(Info, class, loader, constraints) lt;
if (klass1 != NULL && klass2 != NULL) {
@ -282,20 +276,20 @@ bool LoaderConstraintTable::add_entry(Symbol* class_name,
log_ldr_constraint_msg(class_name,
"The class objects presented by loader[0] and loader[1] "
"are different",
class_loader1, class_loader2);
loader1, loader2);
return false;
}
}
InstanceKlass* klass = klass1 != NULL ? klass1 : klass2;
LoaderConstraint* pp1 = find_loader_constraint(class_name, class_loader1);
LoaderConstraint* pp1 = find_loader_constraint(class_name, loader1);
if (pp1 != NULL && pp1->klass() != NULL) {
if (klass != NULL) {
if (klass != pp1->klass()) {
log_ldr_constraint_msg(class_name,
"The class object presented by loader[0] does not match "
"the stored class object in the constraint",
class_loader1, class_loader2);
loader1, loader2);
return false;
}
} else {
@ -303,14 +297,14 @@ bool LoaderConstraintTable::add_entry(Symbol* class_name,
}
}
LoaderConstraint* pp2 = find_loader_constraint(class_name, class_loader2);
LoaderConstraint* pp2 = find_loader_constraint(class_name, loader2);
if (pp2 != NULL && pp2->klass() != NULL) {
if (klass != NULL) {
if (klass != pp2->klass()) {
log_ldr_constraint_msg(class_name,
"The class object presented by loader[1] does not match "
"the stored class object in the constraint",
class_loader1, class_loader2);
loader1, loader2);
return false;
}
} else {
@ -320,15 +314,14 @@ bool LoaderConstraintTable::add_entry(Symbol* class_name,
if (pp1 == NULL && pp2 == NULL) {
add_loader_constraint(class_name, klass, class_loader1(), class_loader2());
add_loader_constraint(class_name, klass, loader1, loader2);
if (lt.is_enabled()) {
ResourceMark rm;
lt.print("adding new constraint for name: %s, loader[0]: %s,"
" loader[1]: %s",
class_name->as_C_string(),
ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id()
);
loader1->loader_name_and_id(),
loader2->loader_name_and_id());
}
} else if (pp1 == pp2) {
/* constraint already imposed */
@ -339,16 +332,15 @@ bool LoaderConstraintTable::add_entry(Symbol* class_name,
lt.print("setting class object in existing constraint for"
" name: %s and loader %s",
class_name->as_C_string(),
ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id()
);
loader1->loader_name_and_id());
}
} else {
assert(pp1->klass() == klass, "loader constraints corrupted");
}
} else if (pp1 == NULL) {
pp2->extend_loader_constraint(class_name, class_loader1, klass);
pp2->extend_loader_constraint(class_name, loader1, klass);
} else if (pp2 == NULL) {
pp1->extend_loader_constraint(class_name, class_loader2, klass);
pp1->extend_loader_constraint(class_name, loader1, klass);
} else {
merge_loader_constraints(class_name, pp1, pp2, klass);
}
@ -359,7 +351,7 @@ bool LoaderConstraintTable::add_entry(Symbol* class_name,
// return true if the constraint was updated, false if the constraint is
// violated
bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
Handle loader,
ClassLoaderData* loader,
Symbol* name) {
LogTarget(Info, class, loader, constraints) lt;
LoaderConstraint* p = find_loader_constraint(name, loader);
@ -369,7 +361,7 @@ bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
lt.print("constraint check failed for name %s, loader %s: "
"the presented class object differs from that stored",
name->as_C_string(),
ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
loader->loader_name_and_id());
}
return false;
} else {
@ -380,7 +372,7 @@ bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
lt.print("updating constraint for name %s, loader %s, "
"by setting class object",
name->as_C_string(),
ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
loader->loader_name_and_id());
}
}
return true;
@ -388,7 +380,7 @@ bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
}
InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
Handle loader) {
ClassLoaderData* loader) {
LoaderConstraint *p = find_loader_constraint(name, loader);
if (p != NULL && p->klass() != NULL) {
assert(p->klass()->is_instance_klass(), "sanity");

View File

@ -35,17 +35,18 @@ class Symbol;
class LoaderConstraintTable : public AllStatic {
private:
static LoaderConstraint* find_loader_constraint(Symbol* name, Handle loader);
static LoaderConstraint* find_loader_constraint(Symbol* name, ClassLoaderData* loader);
static void add_loader_constraint(Symbol* name, InstanceKlass* klass, oop class_loader1, oop class_loader2);
static void add_loader_constraint(Symbol* name, InstanceKlass* klass,
ClassLoaderData* loader1, ClassLoaderData* loader2);
static void merge_loader_constraints(Symbol* class_name, LoaderConstraint* pp1,
LoaderConstraint* pp2, InstanceKlass* klass);
public:
// Check class loader constraints
static bool add_entry(Symbol* name, InstanceKlass* klass1, Handle loader1,
InstanceKlass* klass2, Handle loader2);
static bool add_entry(Symbol* name, InstanceKlass* klass1, ClassLoaderData* loader1,
InstanceKlass* klass2, ClassLoaderData* loader2);
// Note: The main entry point for this module is via SystemDictionary.
// SystemDictionary::check_signature_loaders(Symbol* signature,
@ -53,10 +54,10 @@ public:
// Handle loader1, Handle loader2,
// bool is_method)
static InstanceKlass* find_constrained_klass(Symbol* name, Handle loader);
static InstanceKlass* find_constrained_klass(Symbol* name, ClassLoaderData* loader);
// Class loader constraints
static bool check_or_update(InstanceKlass* k, Handle loader, Symbol* name);
static bool check_or_update(InstanceKlass* k, ClassLoaderData* loader, Symbol* name);
static void purge_loader_constraints();

View File

@ -180,6 +180,11 @@ oop SystemDictionary::get_platform_class_loader_impl(TRAPS) {
return result.get_oop();
}
// Helper function
inline ClassLoaderData* class_loader_data(Handle class_loader) {
return ClassLoaderData::class_loader_data(class_loader());
}
ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool create_mirror_cld) {
if (create_mirror_cld) {
// Add a new class loader data to the graph.
@ -1064,7 +1069,7 @@ bool SystemDictionary::is_shared_class_visible_impl(Symbol* class_name,
// Need to reload it now.
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
if (pkg_name != NULL) {
pkg_entry = ClassLoaderData::class_loader_data(class_loader())->packages()->lookup_only(pkg_name);
pkg_entry = class_loader_data(class_loader)->packages()->lookup_only(pkg_name);
}
}
@ -1180,7 +1185,7 @@ InstanceKlass* SystemDictionary::load_shared_lambda_proxy_class(InstanceKlass* i
// The lambda proxy class and its nest host have the same class loader and class loader data,
// as verified in SystemDictionaryShared::add_lambda_proxy_class()
assert(shared_nest_host->class_loader() == class_loader(), "mismatched class loader");
assert(shared_nest_host->class_loader_data() == ClassLoaderData::class_loader_data(class_loader()), "mismatched class loader data");
assert(shared_nest_host->class_loader_data() == class_loader_data(class_loader), "mismatched class loader data");
ik->set_nest_host(shared_nest_host);
return loaded_ik;
@ -1228,7 +1233,7 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
// loaders, including the bootstrap loader via the placeholder table,
// this lock is currently a nop.
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
ClassLoaderData* loader_data = class_loader_data(class_loader);
{
HandleMark hm(THREAD);
Handle lockObject = get_loader_lock_or_null(class_loader);
@ -1264,12 +1269,11 @@ InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Ha
ResourceMark rm(THREAD);
PackageEntry* pkg_entry = NULL;
bool search_only_bootloader_append = false;
ClassLoaderData *loader_data = class_loader_data(class_loader);
// Find the package in the boot loader's package entry table.
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
if (pkg_name != NULL) {
pkg_entry = loader_data->packages()->lookup_only(pkg_name);
pkg_entry = class_loader_data(class_loader)->packages()->lookup_only(pkg_name);
}
// Prior to attempting to load the class, enforce the boot loader's
@ -1410,22 +1414,22 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* name,
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
if (loaded_class != NULL &&
loaded_class->class_loader() != class_loader()) {
loaded_class->class_loader() != class_loader()) {
check_constraints(loaded_class, class_loader, false, CHECK_NULL);
ClassLoaderData* loader_data = class_loader_data(class_loader);
check_constraints(loaded_class, loader_data, false, CHECK_NULL);
// Record dependency for non-parent delegation.
// This recording keeps the defining class loader of the klass (loaded_class) found
// from being unloaded while the initiating class loader is loaded
// even if the reference to the defining class loader is dropped
// before references to the initiating class loader.
ClassLoaderData* loader_data = class_loader_data(class_loader);
loader_data->record_dependency(loaded_class);
{ // Grabbing the Compile_lock prevents systemDictionary updates
// during compilations.
MutexLocker mu(THREAD, Compile_lock);
update_dictionary(THREAD, loaded_class, class_loader);
update_dictionary(THREAD, loaded_class, loader_data);
}
if (JvmtiExport::should_post_class_load()) {
@ -1469,9 +1473,7 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, Handle class_load
// classloader lock held
// Parallel classloaders will call find_or_define_instance_class
// which will require a token to perform the define class
Symbol* name_h = k->name();
Dictionary* dictionary = loader_data->dictionary();
check_constraints(k, class_loader, true, CHECK);
check_constraints(k, loader_data, true, CHECK);
// Register class just loaded with class loader (placed in ArrayList)
// Note we do this before updating the dictionary, as this can
@ -1495,7 +1497,7 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, Handle class_load
// Add to systemDictionary - so other classes can see it.
// Grabs and releases SystemDictionary_lock
update_dictionary(THREAD, k, class_loader);
update_dictionary(THREAD, k, loader_data);
}
// notify jvmti
@ -1528,7 +1530,7 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, Handle class_load
InstanceKlass* SystemDictionary::find_or_define_helper(Symbol* class_name, Handle class_loader,
InstanceKlass* k, TRAPS) {
Symbol* name_h = k->name(); // passed in class_name may be null
Symbol* name_h = k->name();
ClassLoaderData* loader_data = class_loader_data(class_loader);
Dictionary* dictionary = loader_data->dictionary();
@ -1725,7 +1727,7 @@ void SystemDictionary::initialize(TRAPS) {
// if initiating loader, then ok if InstanceKlass matches existing entry
void SystemDictionary::check_constraints(InstanceKlass* k,
Handle class_loader,
ClassLoaderData* loader_data,
bool defining,
TRAPS) {
ResourceMark rm(THREAD);
@ -1733,8 +1735,7 @@ void SystemDictionary::check_constraints(InstanceKlass* k,
bool throwException = false;
{
Symbol *name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader);
Symbol* name = k->name();
MutexLocker mu(THREAD, SystemDictionary_lock);
@ -1755,13 +1756,13 @@ void SystemDictionary::check_constraints(InstanceKlass* k,
}
if (throwException == false) {
if (LoaderConstraintTable::check_or_update(k, class_loader, name) == false) {
if (LoaderConstraintTable::check_or_update(k, loader_data, name) == false) {
throwException = true;
ss.print("loader constraint violation: loader %s", loader_data->loader_name_and_id());
ss.print(" wants to load %s %s.",
k->external_kind(), k->external_name());
Klass *existing_klass = LoaderConstraintTable::find_constrained_klass(name, class_loader);
if (existing_klass != NULL && existing_klass->class_loader() != class_loader()) {
Klass *existing_klass = LoaderConstraintTable::find_constrained_klass(name, loader_data);
if (existing_klass != NULL && existing_klass->class_loader_data() != loader_data) {
ss.print(" A different %s with the same name was previously loaded by %s. (%s)",
existing_klass->external_kind(),
existing_klass->class_loader_data()->loader_name_and_id(),
@ -1784,23 +1785,20 @@ void SystemDictionary::check_constraints(InstanceKlass* k,
// have been called.
void SystemDictionary::update_dictionary(JavaThread* current,
InstanceKlass* k,
Handle class_loader) {
ClassLoaderData* loader_data) {
// Compile_lock prevents systemDictionary updates during compilations
assert_locked_or_safepoint(Compile_lock);
Symbol* name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader);
Symbol* name = k->name();
{
MutexLocker mu1(SystemDictionary_lock);
MutexLocker mu1(SystemDictionary_lock);
// Make a new dictionary entry.
Dictionary* dictionary = loader_data->dictionary();
InstanceKlass* sd_check = dictionary->find_class(current, name);
if (sd_check == NULL) {
dictionary->add_klass(current, name, k);
}
SystemDictionary_lock->notify_all();
// Make a new dictionary entry.
Dictionary* dictionary = loader_data->dictionary();
InstanceKlass* sd_check = dictionary->find_class(current, name);
if (sd_check == NULL) {
dictionary->add_klass(current, name, k);
}
SystemDictionary_lock->notify_all();
}
@ -1831,7 +1829,7 @@ Klass* SystemDictionary::find_constrained_instance_or_array_klass(
klass = Universe::typeArrayKlassObj(t);
} else {
MutexLocker mu(current, SystemDictionary_lock);
klass = LoaderConstraintTable::find_constrained_klass(ss.as_symbol(), class_loader);
klass = LoaderConstraintTable::find_constrained_klass(ss.as_symbol(), class_loader_data(class_loader));
}
// If element class already loaded, allocate array klass
if (klass != NULL) {
@ -1840,7 +1838,7 @@ Klass* SystemDictionary::find_constrained_instance_or_array_klass(
} else {
MutexLocker mu(current, SystemDictionary_lock);
// Non-array classes are easy: simply check the constraint table.
klass = LoaderConstraintTable::find_constrained_klass(class_name, class_loader);
klass = LoaderConstraintTable::find_constrained_klass(class_name, class_loader_data(class_loader));
}
return klass;
@ -1880,8 +1878,8 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name,
MutexLocker mu_s(SystemDictionary_lock);
InstanceKlass* klass1 = dictionary1->find_class(current, constraint_name);
InstanceKlass* klass2 = dictionary2->find_class(current, constraint_name);
bool result = LoaderConstraintTable::add_entry(constraint_name, klass1, class_loader1,
klass2, class_loader2);
bool result = LoaderConstraintTable::add_entry(constraint_name, klass1, loader_data1,
klass2, loader_data2);
#if INCLUDE_CDS
if (Arguments::is_dumping_archive() && klass_being_linked != NULL &&
!klass_being_linked->is_shared()) {
@ -2443,10 +2441,6 @@ void SystemDictionary::invoke_bootstrap_method(BootstrapInfo& bootstrap_specifie
}
ClassLoaderData* SystemDictionary::class_loader_data(Handle class_loader) {
return ClassLoaderData::class_loader_data(class_loader());
}
bool SystemDictionary::is_nonpublic_Object_method(Method* m) {
assert(m != NULL, "Unexpected NULL Method*");
return !m->is_public() && m->method_holder() == vmClasses::Object_klass();

View File

@ -201,10 +201,6 @@ public:
// Returns java system loader
static oop java_system_loader();
// Returns the class loader data to be used when looking up/updating the
// system dictionary.
static ClassLoaderData *class_loader_data(Handle class_loader);
// Returns java platform loader
static oop java_platform_loader();
@ -381,9 +377,9 @@ protected:
static Symbol* find_placeholder(Symbol* name, ClassLoaderData* loader_data);
// Class loader constraints
static void check_constraints(InstanceKlass* k, Handle loader,
static void check_constraints(InstanceKlass* k, ClassLoaderData* loader,
bool defining, TRAPS);
static void update_dictionary(JavaThread* current, InstanceKlass* k, Handle loader);
static void update_dictionary(JavaThread* current, InstanceKlass* k, ClassLoaderData* loader_data);
};
#endif // SHARE_CLASSFILE_SYSTEMDICTIONARY_HPP