diff --git a/src/hotspot/share/cds/aotConstantPoolResolver.cpp b/src/hotspot/share/cds/aotConstantPoolResolver.cpp index cc500557c8d..584be7085ce 100644 --- a/src/hotspot/share/cds/aotConstantPoolResolver.cpp +++ b/src/hotspot/share/cds/aotConstantPoolResolver.cpp @@ -170,9 +170,7 @@ void AOTConstantPoolResolver::dumptime_resolve_constants(InstanceKlass* ik, TRAP Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, oop class_loader, Symbol* name) { HandleMark hm(current); Handle h_loader(current, class_loader); - Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, - h_loader, - Handle()); + Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, h_loader); if (k != nullptr) { return k; } diff --git a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp index d823db9e8d7..9bab6042436 100644 --- a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp +++ b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp @@ -306,7 +306,7 @@ void AOTLinkedClassBulkLoader::load_hidden_class(ClassLoaderData* loader_data, I // use any special ClassLoaderData. Handle loader(THREAD, loader_data->class_loader()); ResourceMark rm(THREAD); - assert(SystemDictionary::resolve_or_null(ik->name(), loader, pd, THREAD) == nullptr, + assert(SystemDictionary::resolve_or_null(ik->name(), loader, THREAD) == nullptr, "hidden classes cannot be accessible by name: %s", ik->external_name()); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index 57d14229795..47925f578ea 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -612,8 +612,7 @@ void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { // resolve the CP entry for the invokedynamic instruction, which may result in // generation of LambdaForm classes. Handle class_loader(THREAD, SystemDictionary::java_system_loader()); - Handle protection_domain; - Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); + Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, true, CHECK); if (klass->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(klass); MetaspaceShared::try_link_class(THREAD, ik); @@ -781,8 +780,7 @@ InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* inter InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) { Handle class_loader(current, class_loader_oop); - Handle protection_domain; - return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain); + return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader); } InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) { diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 3a7ba936bb0..d2ab109cc72 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -2436,7 +2436,7 @@ void HeapShared::print_stats() { bool HeapShared::is_archived_boot_layer_available(JavaThread* current) { TempNewSymbol klass_name = SymbolTable::new_symbol(ARCHIVED_BOOT_LAYER_CLASS); - InstanceKlass* k = SystemDictionary::find_instance_klass(current, klass_name, Handle(), Handle()); + InstanceKlass* k = SystemDictionary::find_instance_klass(current, klass_name, Handle()); if (k == nullptr) { return false; } else { diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 6bf8f44553d..eb7d1eaf64d 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -462,14 +462,12 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, } Handle loader; - Handle domain; if (accessing_klass != nullptr) { loader = Handle(current, accessing_klass->loader()); - domain = Handle(current, accessing_klass->protection_domain()); } Klass* found_klass = require_local ? - SystemDictionary::find_instance_or_array_klass(current, sym, loader, domain) : + SystemDictionary::find_instance_or_array_klass(current, sym, loader) : SystemDictionary::find_constrained_instance_or_array_klass(current, sym, loader); // If we fail to find an array klass, look again for its element type. @@ -1611,8 +1609,7 @@ void ciEnv::dump_replay_data_helper(outputStream* out) { GrowableArray* objects = _factory->get_ci_metadata(); out->print_cr("# %d ciObject found", objects->length()); - // The very first entry is the InstanceKlass of the root method of the current compilation in order to get the right - // protection domain to load subsequent classes during replay compilation. + // The very first entry is the InstanceKlass of the root method of the current compilation. ciInstanceKlass::dump_replay_instanceKlass(out, task()->method()->method_holder()); for (int i = 0; i < objects->length(); i++) { diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index fd29e0cf857..c4127263df1 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -114,8 +114,6 @@ class CompileReplay : public StackObj { private: FILE* _stream; Thread* _thread; - Handle _protection_domain; - bool _protection_domain_initialized; Handle _loader; int _version; @@ -144,8 +142,6 @@ class CompileReplay : public StackObj { CompileReplay(const char* filename, TRAPS) { _thread = THREAD; _loader = Handle(_thread, SystemDictionary::java_system_loader()); - _protection_domain = Handle(); - _protection_domain_initialized = false; _stream = os::fopen(filename, "rt"); if (_stream == nullptr) { @@ -558,7 +554,7 @@ class CompileReplay : public StackObj { if (_iklass != nullptr) { k = (Klass*)_iklass->find_klass(ciSymbol::make(klass_name->as_C_string()))->constant_encoding(); } else { - k = SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD); + k = SystemDictionary::resolve_or_fail(klass_name, _loader, true, THREAD); } if (HAS_PENDING_EXCEPTION) { oop throwable = PENDING_EXCEPTION; @@ -579,7 +575,7 @@ class CompileReplay : public StackObj { // Lookup a klass Klass* resolve_klass(const char* klass, TRAPS) { Symbol* klass_name = SymbolTable::new_symbol(klass); - return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD); + return SystemDictionary::resolve_or_fail(klass_name, _loader, true, THREAD); } // Parse the standard tuple of @@ -896,18 +892,6 @@ class CompileReplay : public StackObj { // just load the referenced class Klass* k = parse_klass(CHECK); - if (_version >= 1) { - if (!_protection_domain_initialized && k != nullptr) { - assert(_protection_domain() == nullptr, "must be uninitialized"); - // The first entry is the holder class of the method for which a replay compilation is requested. - // Use the same protection domain to load all subsequent classes in order to resolve all classes - // in signatures of inlinees. This ensures that inlining can be done as stated in the replay file. - _protection_domain = Handle(_thread, k->protection_domain()); - } - - _protection_domain_initialized = true; - } - if (k == nullptr) { return; } diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index f108835c9c6..12e7cf1ae9d 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -822,7 +822,6 @@ void ClassFileParser::parse_interfaces(const ClassFileStream* const stream, interf = SystemDictionary::resolve_super_or_fail(_class_name, unresolved_klass, Handle(THREAD, _loader_data->class_loader()), - _protection_domain, false, CHECK); } @@ -5691,7 +5690,6 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st SystemDictionary::resolve_super_or_fail(_class_name, super_class_name, loader, - _protection_domain, true, CHECK); } diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index eecfc9e88a0..73d58ac3687 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -26,26 +26,14 @@ #include "cds/cdsConfig.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/dictionary.hpp" -#include "classfile/javaClasses.hpp" -#include "classfile/protectionDomainCache.hpp" -#include "classfile/systemDictionary.hpp" -#include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/iterator.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" -#include "memory/universe.hpp" -#include "oops/klass.inline.hpp" -#include "oops/method.hpp" -#include "oops/oop.inline.hpp" -#include "oops/oopHandle.inline.hpp" -#include "runtime/handles.inline.hpp" -#include "runtime/javaCalls.hpp" -#include "runtime/mutexLocker.hpp" -#include "runtime/safepointVerifiers.hpp" +#include "oops/instanceKlass.hpp" #include "utilities/concurrentHashTable.inline.hpp" -#include "utilities/growableArray.hpp" +#include "utilities/ostream.hpp" #include "utilities/tableStatistics.hpp" // 2^24 is max size, like StringTable. @@ -69,7 +57,7 @@ Dictionary::~Dictionary() { } uintx Dictionary::Config::get_hash(Value const& value, bool* is_dead) { - return value->instance_klass()->name()->identity_hash(); + return value->name()->identity_hash(); } void* Dictionary::Config::allocate_node(void* context, size_t size, Value const& value) { @@ -77,26 +65,9 @@ void* Dictionary::Config::allocate_node(void* context, size_t size, Value const& } void Dictionary::Config::free_node(void* context, void* memory, Value const& value) { - delete value; // Call DictionaryEntry destructor FreeHeap(memory); } -DictionaryEntry::DictionaryEntry(InstanceKlass* klass) : _instance_klass(klass) { - release_set_package_access_cache(nullptr); -} - -DictionaryEntry::~DictionaryEntry() { - // avoid recursion when deleting linked list - // package_access_cache is accessed during a safepoint. - // This doesn't require a lock because nothing is reading this - // entry anymore. The ClassLoader is dead. - while (package_access_cache_acquire() != nullptr) { - ProtectionDomainEntry* to_delete = package_access_cache_acquire(); - release_set_package_access_cache(to_delete->next_acquire()); - delete to_delete; - } -} - const int _resize_load_trigger = 5; // load factor that will trigger the resize int Dictionary::table_size() const { @@ -108,86 +79,10 @@ bool Dictionary::check_if_needs_resize() { !_table->is_max_size_reached()); } -bool DictionaryEntry::has_package_access_been_granted(Handle protection_domain) { - return protection_domain() == nullptr || !java_lang_System::allow_security_manager() - ? true - : is_in_package_access_cache(protection_domain()); -} - -// Reading the package_access_cache on each DictionaryEntry is lock free and cannot safepoint. -// Adding and deleting entries is under the SystemDictionary_lock -// Deleting unloaded entries on ClassLoaderData for dictionaries that are not unloaded -// is a three step process: -// moving the entries to a separate list, handshake to wait for -// readers to complete (see NSV here), and then actually deleting the entries. -// Deleting entries is done by the ServiceThread when triggered by class unloading. - -bool DictionaryEntry::is_in_package_access_cache(oop protection_domain) const { - assert(Thread::current()->is_Java_thread() || SafepointSynchronize::is_at_safepoint(), - "can only be called by a JavaThread or at safepoint"); - // This cannot safepoint while reading the protection domain set. - NoSafepointVerifier nsv; -#ifdef ASSERT - if (protection_domain == instance_klass()->protection_domain()) { - // Ensure this doesn't show up in the package_access_cache (invariant) - bool in_package_access_cache = false; - for (ProtectionDomainEntry* current = package_access_cache_acquire(); - current != nullptr; - current = current->next_acquire()) { - if (current->object_no_keepalive() == protection_domain) { - in_package_access_cache = true; - break; - } - } - if (in_package_access_cache) { - assert(false, "A klass's protection domain should not show up " - "in its sys. dict. PD set"); - } - } -#endif /* ASSERT */ - - if (protection_domain == instance_klass()->protection_domain()) { - // Succeeds trivially - return true; - } - - for (ProtectionDomainEntry* current = package_access_cache_acquire(); - current != nullptr; - current = current->next_acquire()) { - if (current->object_no_keepalive() == protection_domain) { - return true; - } - } - return false; -} - -void DictionaryEntry::add_to_package_access_cache(ClassLoaderData* loader_data, Handle protection_domain) { - assert_lock_strong(SystemDictionary_lock); - if (!is_in_package_access_cache(protection_domain())) { - WeakHandle obj = ProtectionDomainCacheTable::add_if_absent(protection_domain); - // Additions and deletions hold the SystemDictionary_lock, readers are lock-free - ProtectionDomainEntry* new_head = new ProtectionDomainEntry(obj, _package_access_cache); - release_set_package_access_cache(new_head); - } - LogTarget(Trace, protectiondomain) lt; - if (lt.is_enabled()) { - ResourceMark rm; - LogStream ls(lt); - ls.print("adding protection domain that can access class %s", instance_klass()->name()->as_C_string()); - ls.print(" class loader: "); - loader_data->class_loader()->print_value_on(&ls); - ls.print(" protection domain: "); - protection_domain->print_value_on(&ls); - ls.print(" "); - print_count(&ls); - ls.cr(); - } -} - // Just the classes from defining class loaders void Dictionary::classes_do(void f(InstanceKlass*)) { - auto doit = [&] (DictionaryEntry** value) { - InstanceKlass* k = (*value)->instance_klass(); + auto doit = [&] (InstanceKlass** value) { + InstanceKlass* k = (*value); if (loader_data() == k->class_loader_data()) { f(k); } @@ -199,8 +94,8 @@ void Dictionary::classes_do(void f(InstanceKlass*)) { // All classes, and their class loaders, including initiating class loaders void Dictionary::all_entries_do(KlassClosure* closure) { - auto all_doit = [&] (DictionaryEntry** value) { - InstanceKlass* k = (*value)->instance_klass(); + auto all_doit = [&] (InstanceKlass** value) { + InstanceKlass* k = (*value); closure->do_klass(k); return true; }; @@ -212,9 +107,8 @@ void Dictionary::all_entries_do(KlassClosure* closure) { void Dictionary::classes_do(MetaspaceClosure* it) { assert(CDSConfig::is_dumping_archive(), "sanity"); - auto push = [&] (DictionaryEntry** value) { - InstanceKlass** k = (*value)->instance_klass_addr(); - it->push(k); + auto push = [&] (InstanceKlass** value) { + it->push(value); return true; }; _table->do_scan(Thread::current(), push); @@ -228,26 +122,25 @@ public: uintx get_hash() const { return _name->identity_hash(); } - bool equals(DictionaryEntry** value) { - DictionaryEntry *entry = *value; - return (entry->instance_klass()->name() == _name); + bool equals(InstanceKlass** value) { + InstanceKlass* entry = *value; + return (entry->name() == _name); } - bool is_dead(DictionaryEntry** value) { + bool is_dead(InstanceKlass** value) { return false; } }; // Add a loaded class to the dictionary. void Dictionary::add_klass(JavaThread* current, Symbol* class_name, - InstanceKlass* obj) { + InstanceKlass* klass) { assert_locked_or_safepoint(SystemDictionary_lock); // doesn't matter now - assert(obj != nullptr, "adding nullptr obj"); - assert(obj->name() == class_name, "sanity check on name"); + assert(klass != nullptr, "adding nullptr obj"); + assert(klass->name() == class_name, "sanity check on name"); - DictionaryEntry* entry = new DictionaryEntry(obj); DictionaryLookup lookup(class_name); bool needs_rehashing, clean_hint; - bool created = _table->insert(current, lookup, entry, &needs_rehashing, &clean_hint); + bool created = _table->insert(current, lookup, klass, &needs_rehashing, &clean_hint); assert(created, "should be because we have a lock"); assert (!needs_rehashing, "should never need rehashing"); assert(!clean_hint, "no class should be unloaded"); @@ -277,11 +170,10 @@ void Dictionary::add_klass(JavaThread* current, Symbol* class_name, // Callers should be aware that an entry could be added just after // the table is read here, so the caller will not see the new entry. // The entry may be accessed by the VM thread in verification. -DictionaryEntry* Dictionary::get_entry(Thread* current, - Symbol* class_name) { +InstanceKlass* Dictionary::find_class(Thread* current, Symbol* class_name) { DictionaryLookup lookup(class_name); - DictionaryEntry* result = nullptr; - auto get = [&] (DictionaryEntry** value) { + InstanceKlass* result = nullptr; + auto get = [&] (InstanceKlass** value) { // function called if value is found so is never null result = (*value); }; @@ -291,137 +183,6 @@ DictionaryEntry* Dictionary::get_entry(Thread* current, return result; } -// If SecurityManager is allowed, return the class ONLY IF the protection_domain has been -// granted access to this class by a previous call to Dictionary::check_package_access() -InstanceKlass* Dictionary::find(Thread* current, Symbol* name, - Handle protection_domain) { - NoSafepointVerifier nsv; - - DictionaryEntry* entry = get_entry(current, name); - if (entry != nullptr && entry->has_package_access_been_granted(protection_domain)) { - return entry->instance_klass(); - } else { - return nullptr; - } -} - -InstanceKlass* Dictionary::find_class(Thread* current, - Symbol* name) { - assert_locked_or_safepoint(SystemDictionary_lock); - DictionaryEntry* entry = get_entry(current, name); - return (entry != nullptr) ? entry->instance_klass() : nullptr; -} - -void Dictionary::add_to_package_access_cache(JavaThread* current, - InstanceKlass* klass, - Handle protection_domain) { - assert(java_lang_System::allow_security_manager(), "only needed if security manager allowed"); - Symbol* klass_name = klass->name(); - DictionaryEntry* entry = get_entry(current, klass_name); - - assert(entry != nullptr,"entry must be present, we just created it"); - assert(protection_domain() != nullptr, - "real protection domain should be present"); - - entry->add_to_package_access_cache(loader_data(), protection_domain); - -#ifdef ASSERT - assert(loader_data() != ClassLoaderData::the_null_class_loader_data(), "doesn't make sense"); -#endif - - assert(entry->is_in_package_access_cache(protection_domain()), - "now protection domain should be present"); -} - -inline bool Dictionary::is_in_package_access_cache(JavaThread* current, - Symbol* name, - Handle protection_domain) { - DictionaryEntry* entry = get_entry(current, name); - return entry->has_package_access_been_granted(protection_domain); -} - -void Dictionary::check_package_access(InstanceKlass* klass, - Handle class_loader, - Handle protection_domain, - TRAPS) { - - assert(class_loader() != nullptr, "Should not call this"); - assert(protection_domain() != nullptr, "Should not call this"); -} - -// During class loading we may have cached a protection domain that has -// since been unreferenced, so this entry should be cleared. -void Dictionary::remove_from_package_access_cache(GrowableArray* delete_list) { - assert(Thread::current()->is_Java_thread(), "only called by JavaThread"); - assert_lock_strong(SystemDictionary_lock); - assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder"); - - if (loader_data()->is_the_null_class_loader_data()) { - // Classes in the boot loader are not loaded with protection domains - return; - } - - auto clean_entries = [&] (DictionaryEntry** value) { - DictionaryEntry* probe = *value; - Klass* e = probe->instance_klass(); - - ProtectionDomainEntry* current = probe->package_access_cache_acquire(); - ProtectionDomainEntry* prev = nullptr; - while (current != nullptr) { - if (current->object_no_keepalive() == nullptr) { - LogTarget(Debug, protectiondomain) lt; - if (lt.is_enabled()) { - ResourceMark rm; - // Print out trace information - LogStream ls(lt); - ls.print_cr("PD in set is not alive:"); - ls.print("class loader: "); _loader_data->class_loader()->print_value_on(&ls); - ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls); - ls.cr(); - } - if (probe->package_access_cache_acquire() == current) { - probe->release_set_package_access_cache(current->next_acquire()); - } else { - assert(prev != nullptr, "should be set by alive entry"); - prev->release_set_next(current->next_acquire()); - } - // Mark current for deletion but in the meantime it can still be - // traversed. - delete_list->push(current); - current = current->next_acquire(); - } else { - prev = current; - current = current->next_acquire(); - } - } - return true; - }; - - _table->do_scan(Thread::current(), clean_entries); -} - -void DictionaryEntry::verify_package_access_cache() { - assert(SafepointSynchronize::is_at_safepoint(), "must only be called as safepoint"); - for (ProtectionDomainEntry* current = package_access_cache_acquire(); // accessed at a safepoint - current != nullptr; - current = current->next_acquire()) { - guarantee(oopDesc::is_oop_or_null(current->object_no_keepalive()), "Invalid oop"); - } -} - -void DictionaryEntry::print_count(outputStream *st) { - assert_locked_or_safepoint(SystemDictionary_lock); - int count = 0; - for (ProtectionDomainEntry* current = package_access_cache_acquire(); - current != nullptr; - current = current->next_acquire()) { - count++; - } - st->print("pd set count = #%d", count); -} - -// ---------------------------------------------------------------------------- - void Dictionary::print_size(outputStream* st) const { st->print_cr("Java dictionary (table_size=%d, classes=%d)", table_size(), _number_of_entries); @@ -435,9 +196,8 @@ void Dictionary::print_on(outputStream* st) const { print_size(st); st->print_cr("^ indicates that initiating loader is different from defining loader"); - auto printer = [&] (DictionaryEntry** entry) { - DictionaryEntry* probe = *entry; - Klass* e = probe->instance_klass(); + auto printer = [&] (InstanceKlass** entry) { + InstanceKlass* e = *entry; bool is_defining_class = (_loader_data == e->class_loader_data()); st->print(" %s%s", is_defining_class ? " " : "^", e->external_name()); @@ -448,7 +208,6 @@ void Dictionary::print_on(outputStream* st) const { st->print(", "); cld->print_value_on(st); st->print(", "); - probe->print_count(st); } st->cr(); return true; @@ -462,14 +221,6 @@ void Dictionary::print_on(outputStream* st) const { tty->cr(); } -void DictionaryEntry::verify() { - Klass* e = instance_klass(); - guarantee(e->is_instance_klass(), - "Verify of dictionary failed"); - e->verify(); - verify_package_access_cache(); -} - void Dictionary::verify() { guarantee(_number_of_entries >= 0, "Verify of dictionary failed"); @@ -480,7 +231,7 @@ void Dictionary::verify() { (cld->is_the_null_class_loader_data() || cld->class_loader_no_keepalive()->is_instance()), "checking type of class_loader"); - auto verifier = [&] (DictionaryEntry** val) { + auto verifier = [&] (InstanceKlass** val) { (*val)->verify(); return true; }; @@ -490,7 +241,7 @@ void Dictionary::verify() { void Dictionary::print_table_statistics(outputStream* st, const char* table_name) { static TableStatistics ts; - auto sz = [&] (DictionaryEntry** val) { + auto sz = [&] (InstanceKlass** val) { return sizeof(**val); }; ts = _table->statistics_get(Thread::current(), sz, ts); diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp index fc2747e916a..3f7f381b466 100644 --- a/src/hotspot/share/classfile/dictionary.hpp +++ b/src/hotspot/share/classfile/dictionary.hpp @@ -25,27 +25,21 @@ #ifndef SHARE_CLASSFILE_DICTIONARY_HPP #define SHARE_CLASSFILE_DICTIONARY_HPP -#include "oops/instanceKlass.hpp" -#include "oops/oop.hpp" -#include "oops/oopHandle.hpp" #include "utilities/concurrentHashTable.hpp" -#include "utilities/ostream.hpp" -class DictionaryEntry; -class ProtectionDomainEntry; -template class GrowableArray; +class ClassLoaderData; +class InstanceKlass; +class outputStream; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // The data structure for the class loader data dictionaries. -class DictionaryEntry; - class Dictionary : public CHeapObj { int _number_of_entries; class Config { public: - using Value = DictionaryEntry*; + using Value = InstanceKlass*; static uintx get_hash(Value const& value, bool* is_dead); static void* allocate_node(void* context, size_t size, Value const& value); static void free_node(void* context, void* memory, Value const& value); @@ -57,7 +51,6 @@ class Dictionary : public CHeapObj { ClassLoaderData* _loader_data; // backpointer to owning loader ClassLoaderData* loader_data() const { return _loader_data; } - DictionaryEntry* get_entry(Thread* current, Symbol* name); bool check_if_needs_resize(); int table_size() const; @@ -73,58 +66,11 @@ public: void all_entries_do(KlassClosure* closure); void classes_do(MetaspaceClosure* it); - void remove_from_package_access_cache(GrowableArray* delete_list); - - InstanceKlass* find(Thread* current, Symbol* name, Handle protection_domain); - - // May make Java upcalls to ClassLoader.checkPackageAccess() when a SecurityManager - // is installed. - void check_package_access(InstanceKlass* klass, - Handle class_loader, - Handle protection_domain, - TRAPS); - void print_table_statistics(outputStream* st, const char* table_name); void print_on(outputStream* st) const; void print_size(outputStream* st) const; void verify(); - - private: - bool is_in_package_access_cache(JavaThread* current, Symbol* name, - Handle protection_domain); - void add_to_package_access_cache(JavaThread* current, InstanceKlass* klass, - Handle protection_domain); -}; - -class DictionaryEntry : public CHeapObj { - private: - InstanceKlass* _instance_klass; - - // A cache of the ProtectionDomains that have been granted - // access to the package of _instance_klass by Java up-calls to - // ClassLoader.checkPackageAccess(). See Dictionary::check_package_access(). - // - // We use a cache to avoid repeat Java up-calls that can be expensive. - ProtectionDomainEntry* volatile _package_access_cache; - - public: - DictionaryEntry(InstanceKlass* instance_klass); - ~DictionaryEntry(); - - bool is_in_package_access_cache(oop protection_domain) const; - void add_to_package_access_cache(ClassLoaderData* loader_data, Handle protection_domain); - inline bool has_package_access_been_granted(Handle protection_domain); - void verify_package_access_cache(); - - InstanceKlass* instance_klass() const { return _instance_klass; } - InstanceKlass** instance_klass_addr() { return &_instance_klass; } - - ProtectionDomainEntry* package_access_cache_acquire() const { return Atomic::load_acquire(&_package_access_cache); } - void release_set_package_access_cache(ProtectionDomainEntry* entry) { Atomic::release_store(&_package_access_cache, entry); } - - void print_count(outputStream *st); - void verify(); }; #endif // SHARE_CLASSFILE_DICTIONARY_HPP diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 12d3ef79cd0..2e8f6541418 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1646,7 +1646,7 @@ JFR_ONLY(int java_lang_Thread::_jfr_epoch_offset;) #define THREAD_FIELDS_DO(macro) \ macro(_holder_offset, k, "holder", thread_fieldholder_signature, false); \ macro(_name_offset, k, vmSymbols::name_name(), string_signature, false); \ - macro(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), classloader_signature, false); \ + macro(_contextClassLoader_offset, k, "contextClassLoader", classloader_signature, false); \ macro(_eetop_offset, k, "eetop", long_signature, false); \ macro(_interrupted_offset, k, "interrupted", bool_signature, false); \ macro(_interruptLock_offset, k, "interruptLock", object_signature, false); \ @@ -4721,47 +4721,6 @@ DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdepend return dep_ctx; } -// Support for java_security_AccessControlContext - -int java_security_AccessControlContext::_context_offset; -int java_security_AccessControlContext::_privilegedContext_offset; -int java_security_AccessControlContext::_isPrivileged_offset; -int java_security_AccessControlContext::_isAuthorized_offset; - -#define ACCESSCONTROLCONTEXT_FIELDS_DO(macro) \ - macro(_context_offset, k, "context", protectiondomain_signature, false); \ - macro(_privilegedContext_offset, k, "privilegedContext", accesscontrolcontext_signature, false); \ - macro(_isPrivileged_offset, k, "isPrivileged", bool_signature, false); \ - macro(_isAuthorized_offset, k, "isAuthorized", bool_signature, false) - -void java_security_AccessControlContext::compute_offsets() { - assert(_isPrivileged_offset == 0, "offsets should be initialized only once"); - InstanceKlass* k = vmClasses::AccessControlContext_klass(); - ACCESSCONTROLCONTEXT_FIELDS_DO(FIELD_COMPUTE_OFFSET); -} - -#if INCLUDE_CDS -void java_security_AccessControlContext::serialize_offsets(SerializeClosure* f) { - ACCESSCONTROLCONTEXT_FIELDS_DO(FIELD_SERIALIZE_OFFSET); -} -#endif - -oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) { - assert(_isPrivileged_offset != 0, "offsets should have been initialized"); - assert(_isAuthorized_offset != 0, "offsets should have been initialized"); - // Ensure klass is initialized - vmClasses::AccessControlContext_klass()->initialize(CHECK_NULL); - // Allocate result - oop result = vmClasses::AccessControlContext_klass()->allocate_instance(CHECK_NULL); - // Fill in values - result->obj_field_put(_context_offset, context()); - result->obj_field_put(_privilegedContext_offset, privileged_context()); - result->bool_field_put(_isPrivileged_offset, isPrivileged); - result->bool_field_put(_isAuthorized_offset, true); - return result; -} - - // Support for java_lang_ClassLoader int java_lang_ClassLoader::_loader_data_offset; @@ -4898,17 +4857,6 @@ void java_lang_System::compute_offsets() { SYSTEM_FIELDS_DO(FIELD_COMPUTE_OFFSET); } -// This field tells us that a security manager can never be installed so we -// can completely skip populating the ProtectionDomainCacheTable. -bool java_lang_System::allow_security_manager() { - return false; -} - -// This field tells us that a security manager is installed. -bool java_lang_System::has_security_manager() { - return false; -} - #if INCLUDE_CDS void java_lang_System::serialize_offsets(SerializeClosure* f) { SYSTEM_FIELDS_DO(FIELD_SERIALIZE_OFFSET); @@ -5423,7 +5371,6 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) { f(java_lang_invoke_CallSite) \ f(java_lang_invoke_ConstantCallSite) \ f(java_lang_invoke_MethodHandleNatives_CallSiteContext) \ - f(java_security_AccessControlContext) \ f(java_lang_reflect_AccessibleObject) \ f(java_lang_reflect_Method) \ f(java_lang_reflect_Constructor) \ diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index dcb94878aed..843c8012d2d 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -1480,27 +1480,6 @@ public: static bool is_instance(oop obj); }; -// Interface to java.security.AccessControlContext objects - -class java_security_AccessControlContext: AllStatic { - private: - // Note that for this class the layout changed between JDK1.2 and JDK1.3, - // so we compute the offsets at startup rather than hard-wiring them. - static int _context_offset; - static int _privilegedContext_offset; - static int _isPrivileged_offset; - static int _isAuthorized_offset; - - static void compute_offsets(); - public: - static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; - static oop create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS); - - // Debugging/initialization - friend class JavaClasses; -}; - - // Interface to java.lang.ClassLoader objects #define CLASSLOADER_INJECTED_FIELDS(macro) \ @@ -1557,16 +1536,11 @@ class java_lang_System : AllStatic { static int _static_in_offset; static int _static_out_offset; static int _static_err_offset; - static int _static_security_offset; - static int _static_allow_security_offset; - static int _static_never_offset; public: static int in_offset() { CHECK_INIT(_static_in_offset); } static int out_offset() { CHECK_INIT(_static_out_offset); } static int err_offset() { CHECK_INIT(_static_err_offset); } - static bool allow_security_manager(); - static bool has_security_manager(); static void compute_offsets(); static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; diff --git a/src/hotspot/share/classfile/protectionDomainCache.cpp b/src/hotspot/share/classfile/protectionDomainCache.cpp deleted file mode 100644 index d6c83253ee7..00000000000 --- a/src/hotspot/share/classfile/protectionDomainCache.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/classLoaderDataGraph.hpp" -#include "classfile/dictionary.hpp" -#include "classfile/javaClasses.hpp" -#include "classfile/protectionDomainCache.hpp" -#include "logging/log.hpp" -#include "logging/logStream.hpp" -#include "memory/iterator.hpp" -#include "memory/resourceArea.hpp" -#include "memory/universe.hpp" -#include "oops/oop.inline.hpp" -#include "oops/weakHandle.inline.hpp" -#include "runtime/atomic.hpp" -#include "runtime/mutexLocker.hpp" -#include "utilities/growableArray.hpp" -#include "utilities/resourceHash.hpp" - -unsigned int ProtectionDomainCacheTable::compute_hash(const WeakHandle& protection_domain) { - // The protection domain in the hash computation is passed from a Handle so cannot resolve to null. - assert(protection_domain.peek() != nullptr, "Must be live"); - return (unsigned int)(protection_domain.resolve()->identity_hash()); -} - -bool ProtectionDomainCacheTable::equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2) { - return protection_domain1.peek() == protection_domain2.peek(); -} - -// WeakHandle is both the key and the value. We need it as the key to compare the oops that each point to -// for equality. We need it as the value to return the one that already exists to link in the DictionaryEntry. -using InternalProtectionDomainCacheTable = ResourceHashtable; -static InternalProtectionDomainCacheTable* _pd_cache_table; - -bool ProtectionDomainCacheTable::_dead_entries = false; -int ProtectionDomainCacheTable::_total_oops_removed = 0; - -void ProtectionDomainCacheTable::initialize(){ - _pd_cache_table = new (mtClass) InternalProtectionDomainCacheTable(); -} -void ProtectionDomainCacheTable::trigger_cleanup() { - MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); - _dead_entries = true; - Service_lock->notify_all(); -} - -class CleanProtectionDomainEntries : public CLDClosure { - GrowableArray* _delete_list; - public: - CleanProtectionDomainEntries(GrowableArray* delete_list) : - _delete_list(delete_list) {} - - void do_cld(ClassLoaderData* data) { - Dictionary* dictionary = data->dictionary(); - if (dictionary != nullptr) { - dictionary->remove_from_package_access_cache(_delete_list); - } - } -}; - -static GrowableArray* _delete_list = nullptr; - -class HandshakeForPD : public HandshakeClosure { - public: - HandshakeForPD() : HandshakeClosure("HandshakeForPD") {} - - void do_thread(Thread* thread) { - log_trace(protectiondomain)("HandshakeForPD::do_thread: thread=" - INTPTR_FORMAT, p2i(thread)); - } -}; - -static void purge_deleted_entries() { - // If there are any deleted entries, Handshake-all then they'll be - // safe to remove since traversing the package_access_cache list does not stop for - // safepoints and only JavaThreads will read the package_access_cache. - // This is actually quite rare because the protection domain is generally associated - // with the caller class and class loader, which if still alive will keep this - // protection domain entry alive. - if (_delete_list->length() >= 10) { - HandshakeForPD hs_pd; - Handshake::execute(&hs_pd); - - for (int i = _delete_list->length() - 1; i >= 0; i--) { - ProtectionDomainEntry* entry = _delete_list->at(i); - _delete_list->remove_at(i); - delete entry; - } - assert(_delete_list->length() == 0, "should be cleared"); - } -} - -void ProtectionDomainCacheTable::unlink() { - // DictionaryEntry::_package_access_cache should be null also, so nothing to do. - assert(java_lang_System::allow_security_manager(), "should not be called otherwise"); - - // Create a list for holding deleted entries - if (_delete_list == nullptr) { - _delete_list = new (mtClass) - GrowableArray(20, mtClass); - } - - { - // First clean cached pd lists in loaded CLDs - // It's unlikely, but some loaded classes in a dictionary might - // point to a protection_domain that has been unloaded. - // DictionaryEntry::_package_access_cache points at entries in the ProtectionDomainCacheTable. - MutexLocker ml(ClassLoaderDataGraph_lock); - MutexLocker mldict(SystemDictionary_lock); // need both. - CleanProtectionDomainEntries clean(_delete_list); - ClassLoaderDataGraph::loaded_cld_do(&clean); - } - - // Purge any deleted entries outside of the SystemDictionary_lock. - purge_deleted_entries(); - - // Reacquire the lock to remove entries from the hashtable. - MutexLocker ml(SystemDictionary_lock); - - struct Deleter { - int _oops_removed; - Deleter() : _oops_removed(0) {} - - bool do_entry(WeakHandle& key, WeakHandle& value) { - oop pd = value.peek(); - if (value.peek() == nullptr) { - _oops_removed++; - LogTarget(Debug, protectiondomain, table) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print_cr("protection domain unlinked %d", _oops_removed); - } - value.release(Universe::vm_weak()); - return true; - } else { - return false; - } - } - }; - - Deleter deleter; - _pd_cache_table->unlink(&deleter); - - _total_oops_removed += deleter._oops_removed; - _dead_entries = false; -} - -void ProtectionDomainCacheTable::print_on(outputStream* st) { - assert_locked_or_safepoint(SystemDictionary_lock); - auto printer = [&] (WeakHandle& key, WeakHandle& value) { - st->print_cr(" protection_domain: " PTR_FORMAT, p2i(value.peek())); - }; - st->print_cr("Protection domain cache table (table_size=%d, protection domains=%d)", - _pd_cache_table->table_size(), _pd_cache_table->number_of_entries()); - _pd_cache_table->iterate_all(printer); -} - -void ProtectionDomainCacheTable::verify() { - auto verifier = [&] (WeakHandle& key, WeakHandle& value) { - guarantee(value.peek() == nullptr || oopDesc::is_oop(value.peek()), "must be an oop"); - }; - _pd_cache_table->iterate_all(verifier); -} - -// The object_no_keepalive() call peeks at the phantomly reachable oop without -// keeping it alive. This is used for traversing DictionaryEntry::_package_access_cache. -oop ProtectionDomainEntry::object_no_keepalive() { - return _object.peek(); -} - -WeakHandle ProtectionDomainCacheTable::add_if_absent(Handle protection_domain) { - assert_locked_or_safepoint(SystemDictionary_lock); - WeakHandle w(Universe::vm_weak(), protection_domain); - bool created; - WeakHandle* wk = _pd_cache_table->put_if_absent(w, w, &created); - if (!created) { - // delete the one created since we already had it in the table - w.release(Universe::vm_weak()); - } else { - LogTarget(Debug, protectiondomain, table) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("protection domain added "); - protection_domain->print_value_on(&ls); - ls.cr(); - } - } - // Keep entry alive - (void)wk->resolve(); - return *wk; -} - -void ProtectionDomainCacheTable::print_table_statistics(outputStream* st) { - auto size = [&] (WeakHandle& key, WeakHandle& value) { - // The only storage is in OopStorage for an oop - return sizeof(oop); - }; - TableStatistics ts = _pd_cache_table->statistics_calculate(size); - ts.print(st, "ProtectionDomainCacheTable"); -} - -int ProtectionDomainCacheTable::number_of_entries() { - return _pd_cache_table->number_of_entries(); -} diff --git a/src/hotspot/share/classfile/protectionDomainCache.hpp b/src/hotspot/share/classfile/protectionDomainCache.hpp deleted file mode 100644 index 8ba69d9ab66..00000000000 --- a/src/hotspot/share/classfile/protectionDomainCache.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP -#define SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP - -#include "oops/oop.hpp" -#include "oops/weakHandle.hpp" -#include "runtime/atomic.hpp" - -// The ProtectionDomainCacheTable maps all java.security.ProtectionDomain objects that are -// registered by DictionaryEntry::add_to_package_access_cache() to a unique WeakHandle. -// The amount of different protection domains used is typically magnitudes smaller -// than the number of system dictionary entries (loaded classes). -class ProtectionDomainCacheTable : public AllStatic { - - static bool _dead_entries; - static int _total_oops_removed; - -public: - static void initialize(); - static unsigned int compute_hash(const WeakHandle& protection_domain); - static bool equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2); - - static WeakHandle add_if_absent(Handle protection_domain); - static void unlink(); - - static void print_on(outputStream* st); - static void verify(); - - static bool has_work() { return _dead_entries; } - static void trigger_cleanup(); - - static int removed_entries_count() { return _total_oops_removed; }; - static int number_of_entries(); - static void print_table_statistics(outputStream* st); -}; - - -// This describes the linked list protection domain for each DictionaryEntry in its package_access_cache. -class ProtectionDomainEntry :public CHeapObj { - WeakHandle _object; - ProtectionDomainEntry* volatile _next; - public: - - ProtectionDomainEntry(WeakHandle obj, - ProtectionDomainEntry* head) : _object(obj), _next(head) {} - - ProtectionDomainEntry* next_acquire() { return Atomic::load_acquire(&_next); } - void release_set_next(ProtectionDomainEntry* entry) { Atomic::release_store(&_next, entry); } - oop object_no_keepalive(); -}; -#endif // SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index b9b341c4dab..0cd9886bd01 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -38,7 +38,6 @@ #include "classfile/loaderConstraints.hpp" #include "classfile/packageEntry.hpp" #include "classfile/placeholders.hpp" -#include "classfile/protectionDomainCache.hpp" #include "classfile/resolutionErrors.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" @@ -331,9 +330,9 @@ static void handle_resolution_exception(Symbol* class_name, bool throw_error, TR // Forwards to resolve_or_null -Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, +Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, bool throw_error, TRAPS) { - Klass* klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD); + Klass* klass = resolve_or_null(class_name, class_loader, THREAD); // Check for pending exception or null klass, and throw exception if (HAS_PENDING_EXCEPTION || klass == nullptr) { handle_resolution_exception(class_name, throw_error, CHECK_NULL); @@ -343,9 +342,9 @@ Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader // Forwards to resolve_array_class_or_null or resolve_instance_class_or_null -Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { +Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, TRAPS) { if (Signature::is_array(class_name)) { - return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD); + return resolve_array_class_or_null(class_name, class_loader, THREAD); } else { assert(class_name != nullptr && !Signature::is_array(class_name), "must be"); if (Signature::has_envelope(class_name)) { @@ -353,9 +352,9 @@ Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader // Ignore wrapping L and ;. TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, class_name->utf8_length() - 2); - return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD); + return resolve_instance_class_or_null(name, class_loader, THREAD); } else { - return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD); + return resolve_instance_class_or_null(class_name, class_loader, THREAD); } } } @@ -364,7 +363,6 @@ Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Handle class_loader, - Handle protection_domain, TRAPS) { assert(Signature::is_array(class_name), "must be array"); ResourceMark rm(THREAD); @@ -376,7 +374,6 @@ Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Symbol* obj_class = ss.as_symbol(); k = SystemDictionary::resolve_instance_class_or_null(obj_class, class_loader, - protection_domain, CHECK_NULL); if (k != nullptr) { k = k->array_klass(ndims, CHECK_NULL); @@ -422,7 +419,6 @@ static inline void log_circularity_error(Symbol* name, PlaceholderEntry* probe) InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* class_name, Symbol* next_name, Handle class_loader, - Handle protection_domain, bool is_superclass, TRAPS) { @@ -487,7 +483,6 @@ InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* clas InstanceKlass* superk = SystemDictionary::resolve_instance_class_or_null(next_name, class_loader, - protection_domain, THREAD); // Clean up placeholder entry. @@ -514,7 +509,7 @@ InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* clas static void handle_parallel_super_load(Symbol* name, Symbol* superclassname, Handle class_loader, - Handle protection_domain, TRAPS) { + TRAPS) { // The result superk is not used; resolve_with_circularity_detection is called for circularity check only. // This passes true to is_superclass even though it might not be the super class in order to perform the @@ -522,7 +517,6 @@ static void handle_parallel_super_load(Symbol* name, Klass* superk = SystemDictionary::resolve_with_circularity_detection(name, superclassname, class_loader, - protection_domain, true, CHECK); } @@ -588,7 +582,6 @@ void SystemDictionary::post_class_load_event(EventClassLoad* event, const Instan // This can return null, an exception or an InstanceKlass. InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, - Handle protection_domain, TRAPS) { // name must be in the form of "java/lang/Object" -- cannot be "Ljava/lang/Object;" DEBUG_ONLY(ResourceMark rm(THREAD)); @@ -602,12 +595,8 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, ClassLoaderData* loader_data = register_loader(class_loader); Dictionary* dictionary = loader_data->dictionary(); - // Do lookup to see if class already exists and the protection domain - // has the right access. - // This call uses find which checks protection domain already matches - // All subsequent calls use find_class, and set loaded_class so that - // before we return a result, we call out to java to check for valid protection domain. - InstanceKlass* probe = dictionary->find(THREAD, name, protection_domain); + // Do lookup to see if class already exists. + InstanceKlass* probe = dictionary->find_class(THREAD, name); if (probe != nullptr) return probe; // Non-bootstrap class loaders will call out to class loader and @@ -653,7 +642,6 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, if (circularity_detection_in_progress) { handle_parallel_super_load(name, superclassname, class_loader, - protection_domain, CHECK_NULL); } @@ -738,12 +726,6 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // Make sure we have the right class in the dictionary DEBUG_ONLY(verify_dictionary_entry(name, loaded_class)); - if (protection_domain() != nullptr) { - // A SecurityManager (if installed) may prevent this protection_domain from accessing loaded_class - // by throwing a SecurityException. - dictionary->check_package_access(loaded_class, class_loader, protection_domain, CHECK_NULL); - } - return loaded_class; } @@ -761,8 +743,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, InstanceKlass* SystemDictionary::find_instance_klass(Thread* current, Symbol* class_name, - Handle class_loader, - Handle protection_domain) { + Handle class_loader) { ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(class_loader()); if (loader_data == nullptr) { @@ -772,15 +753,14 @@ InstanceKlass* SystemDictionary::find_instance_klass(Thread* current, } Dictionary* dictionary = loader_data->dictionary(); - return dictionary->find(current, class_name, protection_domain); + return dictionary->find_class(current, class_name); } // Look for a loaded instance or array klass by name. Do not do any loading. // return null in case of error. Klass* SystemDictionary::find_instance_or_array_klass(Thread* current, Symbol* class_name, - Handle class_loader, - Handle protection_domain) { + Handle class_loader) { Klass* k = nullptr; assert(class_name != nullptr, "class name must be non nullptr"); @@ -794,13 +774,13 @@ Klass* SystemDictionary::find_instance_or_array_klass(Thread* current, if (t != T_OBJECT) { k = Universe::typeArrayKlass(t); } else { - k = SystemDictionary::find_instance_klass(current, ss.as_symbol(), class_loader, protection_domain); + k = SystemDictionary::find_instance_klass(current, ss.as_symbol(), class_loader); } if (k != nullptr) { k = k->array_klass_or_null(ndims); } } else { - k = find_instance_klass(current, class_name, class_loader, protection_domain); + k = find_instance_klass(current, class_name, class_loader); } return k; } @@ -1044,8 +1024,7 @@ bool SystemDictionary::is_shared_class_visible_impl(Symbol* class_name, } bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, InstanceKlass* super_type, - Handle class_loader, Handle protection_domain, - bool is_superclass, TRAPS) { + Handle class_loader, bool is_superclass, TRAPS) { assert(super_type->is_shared(), "must be"); // Quick check if the super type has been already loaded. @@ -1055,14 +1034,14 @@ bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, Insta if (!super_type->is_shared_unregistered_class() && super_type->class_loader_data() != nullptr) { // Check if the superclass is loaded by the current class_loader Symbol* name = super_type->name(); - InstanceKlass* check = find_instance_klass(THREAD, name, class_loader, protection_domain); + InstanceKlass* check = find_instance_klass(THREAD, name, class_loader); if (check == super_type) { return true; } } Klass *found = resolve_with_circularity_detection(klass->name(), super_type->name(), - class_loader, protection_domain, is_superclass, CHECK_false); + class_loader, is_superclass, CHECK_false); if (found == super_type) { return true; } else { @@ -1072,8 +1051,7 @@ bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, Insta } } -bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, - Handle protection_domain, TRAPS) { +bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, TRAPS) { // Check the superclass and interfaces. They must be the same // as in dump time, because the layout of depends on // the specific layout of ik->super() and ik->local_interfaces(). @@ -1083,7 +1061,7 @@ bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle if (ik->super() != nullptr) { bool check_super = check_shared_class_super_type(ik, InstanceKlass::cast(ik->super()), - class_loader, protection_domain, true, + class_loader, true, CHECK_false); if (!check_super) { return false; @@ -1093,7 +1071,7 @@ bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle Array* interfaces = ik->local_interfaces(); int num_interfaces = interfaces->length(); for (int index = 0; index < num_interfaces; index++) { - bool check_interface = check_shared_class_super_type(ik, interfaces->at(index), class_loader, protection_domain, false, + bool check_interface = check_shared_class_super_type(ik, interfaces->at(index), class_loader, false, CHECK_false); if (!check_interface) { return false; @@ -1111,7 +1089,7 @@ InstanceKlass* SystemDictionary::load_shared_lambda_proxy_class(InstanceKlass* i InstanceKlass* shared_nest_host = SystemDictionaryShared::get_shared_nest_host(ik); assert(shared_nest_host->is_shared(), "nest host must be in CDS archive"); Symbol* cn = shared_nest_host->name(); - Klass *s = resolve_or_fail(cn, class_loader, protection_domain, true, CHECK_NULL); + Klass *s = resolve_or_fail(cn, class_loader, true, CHECK_NULL); if (s != shared_nest_host) { // The dynamically resolved nest_host is not the same as the one we used during dump time, // so we cannot use ik. @@ -1151,7 +1129,7 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik, return nullptr; } - bool check = check_shared_class_super_types(ik, class_loader, protection_domain, CHECK_NULL); + bool check = check_shared_class_super_types(ik, class_loader, CHECK_NULL); if (!check) { ik->set_shared_loading_failed(); return nullptr; @@ -1579,17 +1557,6 @@ bool SystemDictionary::do_unloading(GCTimer* gc_timer) { if (unloading_occurred) { SymbolTable::trigger_cleanup(); - if (java_lang_System::allow_security_manager()) { - // Oops referenced by the protection domain cache table may get unreachable independently - // of the class loader (eg. cached protection domain oops). So we need to - // explicitly unlink them here. - // All protection domain oops are linked to the caller class, so if nothing - // unloads, this is not needed. - ProtectionDomainCacheTable::trigger_cleanup(); - } else { - assert(ProtectionDomainCacheTable::number_of_entries() == 0, "should be empty"); - } - ConditionalMutexLocker ml(ClassInitError_lock, is_concurrent); InstanceKlass::clean_initialization_error_table(); } @@ -1627,7 +1594,6 @@ void SystemDictionary::initialize(TRAPS) { ResolutionErrorTable::initialize(); LoaderConstraintTable::initialize(); PlaceholderTable::initialize(); - ProtectionDomainCacheTable::initialize(); #if INCLUDE_CDS SystemDictionaryShared::initialize(); #endif @@ -1744,10 +1710,7 @@ Klass* SystemDictionary::find_constrained_instance_or_array_klass( Thread* current, Symbol* class_name, Handle class_loader) { // First see if it has been loaded directly. - // Force the protection domain to be null. (This removes protection checks.) - Handle no_protection_domain; - Klass* klass = find_instance_or_array_klass(current, class_name, class_loader, - no_protection_domain); + Klass* klass = find_instance_or_array_klass(current, class_name, class_loader); if (klass != nullptr) return klass; @@ -2195,21 +2158,18 @@ static bool is_always_visible_class(oop mirror) { // N.B. Code in reflection should use this entry point. Handle SystemDictionary::find_java_mirror_for_type(Symbol* signature, Klass* accessing_klass, - Handle class_loader, - Handle protection_domain, SignatureStream::FailureMode failure_mode, TRAPS) { - assert(accessing_klass == nullptr || (class_loader.is_null() && protection_domain.is_null()), - "one or the other, or perhaps neither"); + + Handle class_loader; // What we have here must be a valid field descriptor, // and all valid field descriptors are supported. // Produce the same java.lang.Class that reflection reports. if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } - ResolvingSignatureStream ss(signature, class_loader, protection_domain, false); + ResolvingSignatureStream ss(signature, class_loader, false); oop mirror_oop = ss.as_java_mirror(failure_mode, CHECK_NH); if (mirror_oop == nullptr) { return Handle(); // report failure this way @@ -2250,10 +2210,9 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, return Handle(); // do not attempt from within compiler, unless it was cached } - Handle class_loader, protection_domain; + Handle class_loader; if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } bool can_be_cached = true; int npts = ArgumentCount(signature).size(); @@ -2265,8 +2224,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, oop mirror = nullptr; if (can_be_cached) { // Use neutral class loader to lookup candidate classes to be placed in the cache. - mirror = ss.as_java_mirror(Handle(), Handle(), - SignatureStream::ReturnNull, CHECK_(empty)); + mirror = ss.as_java_mirror(Handle(), SignatureStream::ReturnNull, CHECK_(empty)); if (mirror == nullptr || (ss.is_reference() && !is_always_visible_class(mirror))) { // Fall back to accessing_klass context. can_be_cached = false; @@ -2274,8 +2232,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, } if (!can_be_cached) { // Resolve, throwing a real error if it doesn't work. - mirror = ss.as_java_mirror(class_loader, protection_domain, - SignatureStream::NCDFError, CHECK_(empty)); + mirror = ss.as_java_mirror(class_loader, SignatureStream::NCDFError, CHECK_(empty)); } assert(mirror != nullptr, "%s", ss.as_symbol()->as_C_string()); if (ss.at_return_type()) @@ -2328,12 +2285,11 @@ Handle SystemDictionary::find_field_handle_type(Symbol* signature, ResourceMark rm(THREAD); SignatureStream ss(signature, /*is_method=*/ false); if (!ss.is_done()) { - Handle class_loader, protection_domain; + Handle class_loader; if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } - oop mirror = ss.as_java_mirror(class_loader, protection_domain, SignatureStream::NCDFError, CHECK_(empty)); + oop mirror = ss.as_java_mirror(class_loader, SignatureStream::NCDFError, CHECK_(empty)); ss.next(); if (ss.is_done()) { return Handle(THREAD, mirror); @@ -2471,9 +2427,6 @@ void SystemDictionary::print_on(outputStream *st) { // loader constraints - print under SD_lock LoaderConstraintTable::print_on(st); st->cr(); - - ProtectionDomainCacheTable::print_on(st); - st->cr(); } void SystemDictionary::print() { print_on(tty); } @@ -2487,9 +2440,6 @@ void SystemDictionary::verify() { // Verify constraint table LoaderConstraintTable::verify(); - - // Verify protection domain table - ProtectionDomainCacheTable::verify(); } void SystemDictionary::dump(outputStream *st, bool verbose) { @@ -2500,7 +2450,6 @@ void SystemDictionary::dump(outputStream *st, bool verbose) { CDS_ONLY(SystemDictionaryShared::print_table_statistics(st)); ClassLoaderDataGraph::print_table_statistics(st); LoaderConstraintTable::print_table_statistics(st); - ProtectionDomainCacheTable::print_table_statistics(st); } } diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 9f5f34ee773..5883b76b64b 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -33,12 +33,12 @@ // The dictionary in each ClassLoaderData stores all loaded classes, either // initiatied by its class loader or defined by its class loader: // -// class loader -> ClassLoaderData -> [class, protection domain set] +// class loader -> ClassLoaderData -> Loaded and initiated loaded classes // // Classes are loaded lazily. The default VM class loader is // represented as null. -// The underlying data structure is an open hash table (Dictionary) per +// The underlying data structure is a concurrent hash table (Dictionary) per // ClassLoaderData with a fixed number of buckets. During loading the // class loader object is locked, (for the VM loader a private lock object is used). // The global SystemDictionary_lock is held for all additions into the ClassLoaderData @@ -49,9 +49,7 @@ // a side data structure, and is used to detect ClassCircularityErrors. // // When class loading is finished, a new entry is added to the dictionary -// of the class loader and the placeholder is removed. Note that the protection -// domain field of the dictionary entry has not yet been filled in when -// the "real" dictionary entry is created. +// of the class loader and the placeholder is removed. // // Clients of this class who are interested in finding if a class has // been completely loaded -- not classes in the process of being loaded -- @@ -91,24 +89,23 @@ class SystemDictionary : AllStatic { // throw_error flag. For most uses the throw_error argument should be set // to true. - static Klass* resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS); + static Klass* resolve_or_fail(Symbol* class_name, Handle class_loader, bool throw_error, TRAPS); // Convenient call for null loader and protection domain. static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS) { - return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD); + return resolve_or_fail(class_name, Handle(), throw_error, THREAD); } // Returns a class with a given class name and class loader. // Loads the class if needed. If not found null is returned. - static Klass* resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); + static Klass* resolve_or_null(Symbol* class_name, Handle class_loader, TRAPS); // Version with null loader and protection domain static Klass* resolve_or_null(Symbol* class_name, TRAPS) { - return resolve_or_null(class_name, Handle(), Handle(), THREAD); + return resolve_or_null(class_name, Handle(), THREAD); } static InstanceKlass* resolve_with_circularity_detection(Symbol* class_name, Symbol* next_name, Handle class_loader, - Handle protection_domain, bool is_superclass, TRAPS); @@ -117,9 +114,8 @@ class SystemDictionary : AllStatic { // "class_name" is the class whose super class or interface is being resolved. static InstanceKlass* resolve_super_or_fail(Symbol* class_name, Symbol* super_name, Handle class_loader, - Handle protection_domain, bool is_superclass, TRAPS) { - return resolve_with_circularity_detection(class_name, super_name, class_loader, protection_domain, - is_superclass, THREAD); + bool is_superclass, TRAPS) { + return resolve_with_circularity_detection(class_name, super_name, class_loader, is_superclass, THREAD); } private: @@ -152,14 +148,13 @@ class SystemDictionary : AllStatic { // Lookup an already loaded class. If not found null is returned. static InstanceKlass* find_instance_klass(Thread* current, Symbol* class_name, - Handle class_loader, Handle protection_domain); + Handle class_loader); // Lookup an already loaded instance or array class. // Do not make any queries to class loaders; consult only the cache. // If not found null is returned. static Klass* find_instance_or_array_klass(Thread* current, Symbol* class_name, - Handle class_loader, - Handle protection_domain); + Handle class_loader); // Lookup an instance or array class that has already been loaded // either into the given class loader, or else into another class @@ -246,21 +241,10 @@ public: static void restore_archived_method_handle_intrinsics() NOT_CDS_RETURN; // compute java_mirror (java.lang.Class instance) for a type ("I", "[[B", "LFoo;", etc.) - // Either the accessing_klass or the CL/PD can be non-null, but not both. static Handle find_java_mirror_for_type(Symbol* signature, Klass* accessing_klass, - Handle class_loader, - Handle protection_domain, SignatureStream::FailureMode failure_mode, TRAPS); - static Handle find_java_mirror_for_type(Symbol* signature, - Klass* accessing_klass, - SignatureStream::FailureMode failure_mode, - TRAPS) { - // callee will fill in CL/PD from AK, if they are needed - return find_java_mirror_for_type(signature, accessing_klass, Handle(), Handle(), - failure_mode, THREAD); - } // find a java.lang.invoke.MethodType object for a given signature // (asks Java to compute it if necessary, except in a compiler thread) @@ -309,10 +293,10 @@ private: // Basic loading operations static InstanceKlass* resolve_instance_class_or_null(Symbol* class_name, Handle class_loader, - Handle protection_domain, TRAPS); + TRAPS); static Klass* resolve_array_class_or_null(Symbol* class_name, Handle class_loader, - Handle protection_domain, TRAPS); + TRAPS); static void define_instance_class(InstanceKlass* k, Handle class_loader, TRAPS); static InstanceKlass* find_or_define_helper(Symbol* class_name, Handle class_loader, @@ -334,10 +318,9 @@ private: PackageEntry* pkg_entry, Handle class_loader); static bool check_shared_class_super_type(InstanceKlass* klass, InstanceKlass* super, - Handle class_loader, Handle protection_domain, + Handle class_loader, bool is_superclass, TRAPS); - static bool check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, - Handle protection_domain, TRAPS); + static bool check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, TRAPS); // Second part of load_shared_class static void load_shared_class_misc(InstanceKlass* ik, ClassLoaderData* loader_data) NOT_CDS_RETURN; static void restore_archived_method_handle_intrinsics_impl(TRAPS) NOT_CDS_RETURN; diff --git a/src/hotspot/share/classfile/verificationType.cpp b/src/hotspot/share/classfile/verificationType.cpp index bd66cf43b5c..ddeee499814 100644 --- a/src/hotspot/share/classfile/verificationType.cpp +++ b/src/hotspot/share/classfile/verificationType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,8 +57,7 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym this_class = klass; } else { this_class = SystemDictionary::resolve_or_fail( - name, Handle(THREAD, klass->class_loader()), - Handle(THREAD, klass->protection_domain()), true, CHECK_false); + name, Handle(THREAD, klass->class_loader()), true, CHECK_false); if (log_is_enabled(Debug, class, resolve)) { Verifier::trace_class_resolution(this_class, klass); } @@ -79,8 +78,7 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym from_class = klass; } else { from_class = SystemDictionary::resolve_or_fail( - from_name, Handle(THREAD, klass->class_loader()), - Handle(THREAD, klass->protection_domain()), true, CHECK_false); + from_name, Handle(THREAD, klass->class_loader()), true, CHECK_false); if (log_is_enabled(Debug, class, resolve)) { Verifier::trace_class_resolution(from_class, klass); } diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index e8dc8bcfdc9..ef3caff6476 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -2092,15 +2092,13 @@ void ClassVerifier::class_format_error(const char* msg, ...) { Klass* ClassVerifier::load_class(Symbol* name, TRAPS) { HandleMark hm(THREAD); - // Get current loader and protection domain first. + // Get current loader first. oop loader = current_class()->class_loader(); - oop protection_domain = current_class()->protection_domain(); assert(name_in_supers(name, current_class()), "name should be a super class"); Klass* kls = SystemDictionary::resolve_or_fail( - name, Handle(THREAD, loader), Handle(THREAD, protection_domain), - true, THREAD); + name, Handle(THREAD, loader), true, THREAD); if (kls != nullptr) { if (log_is_enabled(Debug, class, resolve)) { diff --git a/src/hotspot/share/classfile/vmClassMacros.hpp b/src/hotspot/share/classfile/vmClassMacros.hpp index 46d601d17dd..395034d4a21 100644 --- a/src/hotspot/share/classfile/vmClassMacros.hpp +++ b/src/hotspot/share/classfile/vmClassMacros.hpp @@ -60,10 +60,7 @@ do_klass(Error_klass, java_lang_Error ) \ do_klass(Exception_klass, java_lang_Exception ) \ do_klass(RuntimeException_klass, java_lang_RuntimeException ) \ - do_klass(SecurityManager_klass, java_lang_SecurityManager ) \ do_klass(ProtectionDomain_klass, java_security_ProtectionDomain ) \ - do_klass(AccessControlContext_klass, java_security_AccessControlContext ) \ - do_klass(AccessController_klass, java_security_AccessController ) \ do_klass(SecureClassLoader_klass, java_security_SecureClassLoader ) \ do_klass(ClassNotFoundException_klass, java_lang_ClassNotFoundException ) \ do_klass(Record_klass, java_lang_Record ) \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 0728e156f82..ca451572de7 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -118,12 +118,8 @@ class SerializeClosure; template(java_lang_reflect_RecordComponent, "java/lang/reflect/RecordComponent") \ template(java_lang_StringBuffer, "java/lang/StringBuffer") \ template(java_lang_StringBuilder, "java/lang/StringBuilder") \ - template(java_lang_SecurityManager, "java/lang/SecurityManager") \ template(java_lang_ScopedValue, "java/lang/ScopedValue") \ template(java_lang_ScopedValue_Carrier, "java/lang/ScopedValue$Carrier") \ - template(java_security_AccessControlContext, "java/security/AccessControlContext") \ - template(java_security_AccessController, "java/security/AccessController") \ - template(executePrivileged_name, "executePrivileged") \ template(java_security_CodeSource, "java/security/CodeSource") \ template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \ template(java_security_SecureClassLoader, "java/security/SecureClassLoader") \ @@ -440,9 +436,6 @@ class SerializeClosure; template(getCause_name, "getCause") \ template(initCause_name, "initCause") \ template(getProperty_name, "getProperty") \ - template(context_name, "context") \ - template(contextClassLoader_name, "contextClassLoader") \ - template(getClassContext_name, "getClassContext") \ template(wait_name, "wait0") \ template(forName_name, "forName") \ template(forName0_name, "forName0") \ @@ -490,7 +483,6 @@ class SerializeClosure; template(input_stream_void_signature, "(Ljava/io/InputStream;)V") \ template(input_stream_signature, "Ljava/io/InputStream;") \ template(print_stream_signature, "Ljava/io/PrintStream;") \ - template(security_manager_signature, "Ljava/lang/SecurityManager;") \ template(defineOrCheckPackage_name, "defineOrCheckPackage") \ template(defineOrCheckPackage_signature, "(Ljava/lang/String;Ljava/util/jar/Manifest;Ljava/net/URL;)Ljava/lang/Package;") \ template(getProtectionDomain_name, "getProtectionDomain") \ @@ -604,9 +596,6 @@ class SerializeClosure; template(void_string_signature, "()Ljava/lang/String;") \ template(object_array_object_signature, "([Ljava/lang/Object;)Ljava/lang/Object;") \ template(object_object_array_object_signature, "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")\ - template(protectiondomain_signature, "[Ljava/security/ProtectionDomain;") \ - template(accesscontrolcontext_signature, "Ljava/security/AccessControlContext;") \ - template(class_protectiondomain_signature, "(Ljava/lang/Class;Ljava/security/ProtectionDomain;)V") \ template(thread_signature, "Ljava/lang/Thread;") \ template(thread_fieldholder_signature, "Ljava/lang/Thread$FieldHolder;") \ template(threadgroup_signature, "Ljava/lang/ThreadGroup;") \ diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index e50d758335c..bc46a2cf852 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -326,12 +326,6 @@ JVM_GetNextThreadIdOffset(JNIEnv *env, jclass threadClass); JNIEXPORT void JNICALL JVM_RegisterContinuationMethods(JNIEnv *env, jclass cls); -/* - * java.lang.SecurityManager - */ -JNIEXPORT jobjectArray JNICALL -JVM_GetClassContext(JNIEnv *env); - /* * java.lang.Package */ diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index 92d95b43e40..6300b660092 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -496,7 +496,6 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, Klass* natives = vmClasses::MethodHandleNatives_klass(); if (natives == nullptr || InstanceKlass::cast(natives)->is_not_initialized()) { SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), - Handle(), Handle(), true, CHECK_NULL); diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 3599df18544..aa8ce28b7c5 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -613,10 +613,8 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU JVMCIKlassHandle resolved_klass(THREAD); Klass* accessing_klass = UNPACK_PAIR(Klass, accessing_klass); Handle class_loader; - Handle protection_domain; if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } else { switch (accessing_klass_loader) { case 0: break; // class_loader is already null, the boot loader @@ -629,23 +627,21 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU } if (resolve) { - resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, protection_domain, true, CHECK_NULL); + resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, true, CHECK_NULL); } else { if (Signature::has_envelope(class_name)) { // This is a name from a signature. Strip off the trimmings. // Call recursive to keep scope of strippedsym. TempNewSymbol strippedsym = Signature::strip_envelope(class_name); resolved_klass = SystemDictionary::find_instance_klass(THREAD, strippedsym, - class_loader, - protection_domain); + class_loader); } else if (Signature::is_array(class_name)) { SignatureStream ss(class_name, false); int ndim = ss.skip_array_prefix(); if (ss.type() == T_OBJECT) { Symbol* strippedsym = ss.as_symbol(); resolved_klass = SystemDictionary::find_instance_klass(THREAD, strippedsym, - class_loader, - protection_domain); + class_loader); if (!resolved_klass.is_null()) { resolved_klass = resolved_klass->array_klass(ndim, CHECK_NULL); } @@ -654,8 +650,7 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU } } else { resolved_klass = SystemDictionary::find_instance_klass(THREAD, class_name, - class_loader, - protection_domain); + class_loader); } } JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 129a88ac4d7..c930910dd44 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -941,9 +941,8 @@ void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) va_end(ap); JavaThread* THREAD = JavaThread::current(); if (is_hotspot()) { - Handle h_loader = Handle(); - Handle h_protection_domain = Handle(); - Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain); + Handle h_loader; + Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader ); } else { JNIAccessMark jni(this, THREAD); jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 8241fc2498c..ac972e97b1b 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -1678,14 +1678,12 @@ Klass* JVMCIRuntime::get_klass_by_name_impl(Klass*& accessing_klass, } Handle loader; - Handle domain; if (accessing_klass != nullptr) { loader = Handle(THREAD, accessing_klass->class_loader()); - domain = Handle(THREAD, accessing_klass->protection_domain()); } Klass* found_klass = require_local ? - SystemDictionary::find_instance_or_array_klass(THREAD, sym, loader, domain) : + SystemDictionary::find_instance_or_array_klass(THREAD, sym, loader) : SystemDictionary::find_constrained_instance_or_array_klass(THREAD, sym, loader); // If we fail to find an array klass, look again for its element type. diff --git a/src/hotspot/share/logging/logDiagnosticCommand.hpp b/src/hotspot/share/logging/logDiagnosticCommand.hpp index 089bcdc48af..e63509bea9e 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.hpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,6 @@ class LogDiagnosticCommand : public DCmdWithParser { return "Lists current log configuration, enables/disables/configures a log output, or rotates all logs."; } - // Used by SecurityManager. This DCMD requires ManagementPermission = control. static const JavaPermission permission() { JavaPermission p = {"java.lang.management.ManagementPermission", "control", nullptr}; return p; diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index d9563e41ce7..15ac30d09ab 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -161,7 +161,6 @@ class outputStream; LOG_TAG(preorder) /* Trace all classes loaded in order referenced (not loaded) */ \ LOG_TAG(preview) /* Trace loading of preview feature types */ \ LOG_TAG(promotion) \ - LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \ LOG_TAG(ptrqueue) \ LOG_TAG(purge) \ LOG_TAG(record) \ diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index a435d6e5fd3..73cc16bc122 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -680,13 +680,12 @@ Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int cp_ind Handle mirror_handle; Symbol* name = this_cp->symbol_at(name_index); Handle loader (THREAD, this_cp->pool_holder()->class_loader()); - Handle protection_domain (THREAD, this_cp->pool_holder()->protection_domain()); Klass* k; { // Turn off the single stepping while doing class resolution JvmtiHideSingleStepping jhss(javaThread); - k = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD); + k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD); } // JvmtiHideSingleStepping jhss(javaThread); if (!HAS_PENDING_EXCEPTION) { @@ -756,10 +755,8 @@ Klass* ConstantPool::klass_at_if_loaded(const constantPoolHandle& this_cp, int w HandleMark hm(current); Symbol* name = this_cp->symbol_at(name_index); oop loader = this_cp->pool_holder()->class_loader(); - oop protection_domain = this_cp->pool_holder()->protection_domain(); - Handle h_prot (current, protection_domain); Handle h_loader (current, loader); - Klass* k = SystemDictionary::find_instance_klass(current, name, h_loader, h_prot); + Klass* k = SystemDictionary::find_instance_klass(current, name, h_loader); // Avoid constant pool verification at a safepoint, as it takes the Module_lock. if (k != nullptr && current->is_Java_thread()) { diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 917c93304c1..af10efc0f00 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -927,8 +927,7 @@ bool Method::is_klass_loaded_by_klass_index(int klass_index) const { Thread *thread = Thread::current(); Symbol* klass_name = constants()->klass_name_at(klass_index); Handle loader(thread, method_holder()->class_loader()); - Handle prot (thread, method_holder()->protection_domain()); - return SystemDictionary::find_instance_klass(thread, klass_name, loader, prot) != nullptr; + return SystemDictionary::find_instance_klass(thread, klass_name, loader) != nullptr; } else { return true; } diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index b27448dd39a..7bea3441fa5 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -321,8 +321,6 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name)) SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_NoClassDefFoundError(), CHECK_NULL); - //%note jni_3 - Handle protection_domain; // Find calling class Klass* k = thread->security_get_caller_class(0); // default to the system loader when no context @@ -344,15 +342,13 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name)) if (mirror != nullptr) { Klass* fromClass = java_lang_Class::as_Klass(mirror); loader = Handle(THREAD, fromClass->class_loader()); - protection_domain = Handle(THREAD, fromClass->protection_domain()); } } else { loader = Handle(THREAD, k->class_loader()); } } - result = find_class_from_class_loader(env, class_name, true, loader, - protection_domain, true, thread); + result = find_class_from_class_loader(env, class_name, true, loader, true, thread); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); @@ -537,8 +533,7 @@ JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message)) InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); Symbol* name = k->name(); Handle class_loader (THREAD, k->class_loader()); - Handle protection_domain (THREAD, k->protection_domain()); - THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK); + THROW_MSG_LOADER_(name, (char *)message, class_loader, JNI_OK); ShouldNotReachHere(); return 0; // Mute compiler. JNI_END @@ -2929,10 +2924,9 @@ static jfieldID bufferCapacityField = nullptr; static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) { Handle loader; // null (bootstrap) loader - Handle protection_domain; // null protection domain TempNewSymbol sym = SymbolTable::new_symbol(name); - jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); + jclass result = find_class_from_class_loader(env, sym, true, loader, true, CHECK_NULL); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 3288f2eefe4..b8e7f9c1ea2 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -151,29 +151,22 @@ and thus can only support use of handles passed in. */ -static void trace_class_resolution_impl(Klass* to_class, TRAPS) { +extern void trace_class_resolution(Klass* to_class) { ResourceMark rm; int line_number = -1; const char * source_file = nullptr; const char * trace = "explicit"; InstanceKlass* caller = nullptr; - JavaThread* jthread = THREAD; + JavaThread* jthread = JavaThread::current(); if (jthread->has_last_Java_frame()) { vframeStream vfst(jthread); - // scan up the stack skipping ClassLoader, AccessController and PrivilegedAction frames - TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController"); - Klass* access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK); - TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction"); - Klass* privileged_action_klass = SystemDictionary::resolve_or_fail(privileged_action, false, CHECK); - + // Scan up the stack skipping ClassLoader frames. Method* last_caller = nullptr; while (!vfst.at_end()) { Method* m = vfst.method(); - if (!vfst.method()->method_holder()->is_subclass_of(vmClasses::ClassLoader_klass())&& - !vfst.method()->method_holder()->is_subclass_of(access_controller_klass) && - !vfst.method()->method_holder()->is_subclass_of(privileged_action_klass)) { + if (!vfst.method()->method_holder()->is_subclass_of(vmClasses::ClassLoader_klass())) { break; } last_caller = m; @@ -232,14 +225,6 @@ static void trace_class_resolution_impl(Klass* to_class, TRAPS) { } } -void trace_class_resolution(Klass* to_class) { - EXCEPTION_MARK; - trace_class_resolution_impl(to_class, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - } -} - // java.lang.System ////////////////////////////////////////////////////////////////////// @@ -833,20 +818,10 @@ JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name, oop loader_oop = JNIHandles::resolve(loader); oop from_class = JNIHandles::resolve(caller); - oop protection_domain = nullptr; - // If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get - // NPE. Put it in another way, the bootstrap class loader has all permission and - // thus no checkPackageAccess equivalence in the VM class loader. - // The caller is also passed as null by the java code if there is no security - // manager to avoid the performance cost of getting the calling class. - if (from_class != nullptr && loader_oop != nullptr) { - protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain(); - } - Handle h_loader(THREAD, loader_oop); - Handle h_prot(THREAD, protection_domain); + jclass result = find_class_from_class_loader(env, h_name, init, h_loader, - h_prot, false, THREAD); + false, THREAD); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); @@ -865,15 +840,11 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, ? (Klass*)nullptr : java_lang_Class::as_Klass(from_class_oop); oop class_loader = nullptr; - oop protection_domain = nullptr; if (from_class != nullptr) { class_loader = from_class->class_loader(); - protection_domain = from_class->protection_domain(); } Handle h_loader(THREAD, class_loader); - Handle h_prot (THREAD, protection_domain); - jclass result = find_class_from_class_loader(env, h_name, init, h_loader, - h_prot, true, thread); + jclass result = find_class_from_class_loader(env, h_name, init, h_loader, true, thread); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { // this function is generally only used for class loading during verification. @@ -1121,9 +1092,7 @@ JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name) // The Java level wrapper will perform the necessary security check allowing // us to pass the null as the initiating class loader. Handle h_loader(THREAD, JNIHandles::resolve(loader)); - Klass* k = SystemDictionary::find_instance_or_array_klass(THREAD, klass_name, - h_loader, - Handle()); + Klass* k = SystemDictionary::find_instance_or_array_klass(THREAD, klass_name, h_loader); #if INCLUDE_CDS if (k == nullptr) { // If the class is not already loaded, try to see if it's in the shared @@ -3069,45 +3038,6 @@ JVM_ENTRY(void, JVM_SetScopedValueCache(JNIEnv* env, jclass threadClass, thread->set_scopedValueCache(objs); JVM_END -// java.lang.SecurityManager /////////////////////////////////////////////////////////////////////// - -JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) - ResourceMark rm(THREAD); - JvmtiVMObjectAllocEventCollector oam; - vframeStream vfst(thread); - - if (vmClasses::reflect_CallerSensitive_klass() != nullptr) { - // This must only be called from SecurityManager.getClassContext - Method* m = vfst.method(); - if (!(m->method_holder() == vmClasses::SecurityManager_klass() && - m->name() == vmSymbols::getClassContext_name() && - m->signature() == vmSymbols::void_class_array_signature())) { - THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); - } - } - - // Collect method holders - GrowableArray* klass_array = new GrowableArray(); - for (; !vfst.at_end(); vfst.security_next()) { - Method* m = vfst.method(); - // Native frames are not returned - if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { - Klass* holder = m->method_holder(); - assert(holder->is_klass(), "just checking"); - klass_array->append(holder); - } - } - - // Create result array of type [Ljava/lang/Class; - objArrayOop result = oopFactory::new_objArray(vmClasses::Class_klass(), klass_array->length(), CHECK_NULL); - // Fill in mirrors corresponding to method holders - for (int i = 0; i < klass_array->length(); i++) { - result->obj_at_put(i, klass_array->at(i)->java_mirror()); - } - - return (jobjectArray) JNIHandles::make_local(THREAD, result); -JVM_END - // java.lang.Package //////////////////////////////////////////////////////////////// @@ -3421,15 +3351,8 @@ JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) { // Shared JNI/JVM entry points ////////////////////////////////////////////////////////////// jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, - Handle loader, Handle protection_domain, - jboolean throwError, TRAPS) { - // Security Note: - // The Java level wrapper will perform the necessary security check allowing - // us to pass the null as the initiating class loader. The VM is responsible for - // the checkPackageAccess relative to the initiating class loader via the - // protection_domain. The protection_domain is passed as null by the java code - // if there is no security manager in 3-arg Class.forName(). - Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL); + Handle loader, jboolean throwError, TRAPS) { + Klass* klass = SystemDictionary::resolve_or_fail(name, loader, throwError != 0, CHECK_NULL); // Check if we should initialize the class if (init && klass->is_instance_klass()) { diff --git a/src/hotspot/share/prims/jvm_misc.hpp b/src/hotspot/share/prims/jvm_misc.hpp index 28b39631bf4..18c8e3b6ad5 100644 --- a/src/hotspot/share/prims/jvm_misc.hpp +++ b/src/hotspot/share/prims/jvm_misc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ // Useful entry points shared by JNI and JVM interface. // We do not allow real JNI or JVM entry point to call each other. -jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS); +jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, jboolean throwError, TRAPS); void trace_class_resolution(Klass* to_class); diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index d4b5e293c09..a8607bb2efd 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -35,7 +35,6 @@ #include "classfile/classPrinter.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/modules.hpp" -#include "classfile/protectionDomainCache.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -2536,10 +2535,6 @@ WB_ENTRY(jlong, WB_ResolvedMethodItemsCount(JNIEnv* env, jobject o)) return (jlong) ResolvedMethodTable::items_count(); WB_END -WB_ENTRY(jint, WB_ProtectionDomainRemovedCount(JNIEnv* env, jobject o)) - return (jint) ProtectionDomainCacheTable::removed_entries_count(); -WB_END - WB_ENTRY(jint, WB_GetKlassMetadataSize(JNIEnv* env, jobject wb, jclass mirror)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(mirror)); // Return size in bytes. @@ -2966,7 +2961,6 @@ static JNINativeMethod methods[] = { {CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo }, {CC"disableElfSectionCache", CC"()V", (void*)&WB_DisableElfSectionCache }, {CC"resolvedMethodItemsCount", CC"()J", (void*)&WB_ResolvedMethodItemsCount }, - {CC"protectionDomainRemovedCount", CC"()I", (void*)&WB_ProtectionDomainRemovedCount }, {CC"getKlassMetadataSize", CC"(Ljava/lang/Class;)I",(void*)&WB_GetKlassMetadataSize}, {CC"createMetaspaceTestContext", CC"(JJ)J", (void*)&WB_CreateMetaspaceTestContext}, diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 9992d42622f..10fd83750d4 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1065,7 +1065,7 @@ protected: static InstanceKlass* find_cache_klass(Thread* thread, Symbol* klass_name) { ResourceMark rm(thread); char* klass_name_str = klass_name->as_C_string(); - InstanceKlass* ik = SystemDictionary::find_instance_klass(thread, klass_name, Handle(), Handle()); + InstanceKlass* ik = SystemDictionary::find_instance_klass(thread, klass_name, Handle()); guarantee(ik != nullptr, "%s must be loaded", klass_name_str); if (!ik->is_in_error_state()) { guarantee(ik->is_initialized(), "%s must be initialized", klass_name_str); diff --git a/src/hotspot/share/runtime/serviceThread.cpp b/src/hotspot/share/runtime/serviceThread.cpp index f5653ccd5f4..f4bffc72ef3 100644 --- a/src/hotspot/share/runtime/serviceThread.cpp +++ b/src/hotspot/share/runtime/serviceThread.cpp @@ -25,11 +25,8 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/protectionDomainCache.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" -#include "classfile/systemDictionary.hpp" -#include "classfile/vmClasses.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/shared/oopStorageSet.hpp" #include "interpreter/oopMapCache.hpp" @@ -40,15 +37,10 @@ #include "prims/resolvedMethodTable.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" -#include "runtime/java.hpp" -#include "runtime/javaCalls.hpp" -#include "runtime/jniHandles.hpp" #include "runtime/lightweightSynchronizer.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "runtime/serviceThread.hpp" -#include "services/diagnosticArgument.hpp" -#include "services/diagnosticFramework.hpp" #include "services/finalizerService.hpp" #include "services/gcNotifier.hpp" #include "services/lowMemoryDetector.hpp" @@ -88,7 +80,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { bool finalizerservice_work = false; bool resolved_method_table_work = false; bool thread_id_table_work = false; - bool protection_domain_table_work = false; bool oopstorage_work = false; JvmtiDeferredEvent jvmti_event; bool oop_handles_to_release = false; @@ -118,7 +109,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { (finalizerservice_work = FinalizerService::has_work()) | (resolved_method_table_work = ResolvedMethodTable::has_work()) | (thread_id_table_work = ThreadIdTable::has_work()) | - (protection_domain_table_work = ProtectionDomainCacheTable::has_work()) | (oopstorage_work = OopStorage::has_cleanup_work_and_reset()) | (oop_handles_to_release = JavaThread::has_oop_handles_to_release()) | (cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) | @@ -163,10 +153,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { ThreadIdTable::do_concurrent_work(jt); } - if (protection_domain_table_work) { - ProtectionDomainCacheTable::unlink(); - } - if (oopstorage_work) { cleanup_oopstorages(); } diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp index 081bdd2e0d3..2dfb8d81037 100644 --- a/src/hotspot/share/runtime/signature.cpp +++ b/src/hotspot/share/runtime/signature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -501,8 +501,7 @@ Symbol* SignatureStream::find_symbol() { return name; } -Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, - FailureMode failure_mode, TRAPS) { +Klass* SignatureStream::as_klass(Handle class_loader, FailureMode failure_mode, TRAPS) { if (!is_reference()) { return nullptr; } @@ -511,11 +510,11 @@ Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, if (failure_mode == ReturnNull) { // Note: SD::resolve_or_null returns null for most failure modes, // but not all. Circularity errors, invalid PDs, etc., throw. - k = SystemDictionary::resolve_or_null(name, class_loader, protection_domain, CHECK_NULL); + k = SystemDictionary::resolve_or_null(name, class_loader, CHECK_NULL); } else if (failure_mode == CachedOrNull) { NoSafepointVerifier nsv; // no loading, now, we mean it! assert(!HAS_PENDING_EXCEPTION, ""); - k = SystemDictionary::find_instance_klass(THREAD, name, class_loader, protection_domain); + k = SystemDictionary::find_instance_klass(THREAD, name, class_loader); // SD::find does not trigger loading, so there should be no throws // Still, bad things can happen, so we CHECK_NULL and ask callers // to do likewise. @@ -525,18 +524,17 @@ Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, // The test here allows for an additional mode CNFException // if callers need to request the reflective error instead. bool throw_error = (failure_mode == NCDFError); - k = SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, CHECK_NULL); + k = SystemDictionary::resolve_or_fail(name, class_loader, throw_error, CHECK_NULL); } return k; } -oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, - FailureMode failure_mode, TRAPS) { +oop SignatureStream::as_java_mirror(Handle class_loader, FailureMode failure_mode, TRAPS) { if (!is_reference()) { return Universe::java_mirror(type()); } - Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); + Klass* klass = as_klass(class_loader, failure_mode, CHECK_NULL); if (klass == nullptr) { return nullptr; } @@ -551,10 +549,8 @@ void SignatureStream::skip_to_return_type() { ResolvingSignatureStream::ResolvingSignatureStream(Symbol* signature, Handle class_loader, - Handle protection_domain, bool is_method) - : SignatureStream(signature, is_method), - _class_loader(class_loader), _protection_domain(protection_domain) + : SignatureStream(signature, is_method), _class_loader(class_loader) { initialize_load_origin(nullptr); } @@ -576,7 +572,6 @@ void ResolvingSignatureStream::cache_handles() { assert(_load_origin != nullptr, ""); JavaThread* current = JavaThread::current(); _class_loader = Handle(current, _load_origin->class_loader()); - _protection_domain = Handle(current, _load_origin->protection_domain()); } #ifdef ASSERT diff --git a/src/hotspot/share/runtime/signature.hpp b/src/hotspot/share/runtime/signature.hpp index 25de9c0a1f0..ef18b0f03d3 100644 --- a/src/hotspot/share/runtime/signature.hpp +++ b/src/hotspot/share/runtime/signature.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -562,8 +562,8 @@ class SignatureStream : public StackObj { // free-standing lookups (bring your own CL/PD pair) enum FailureMode { ReturnNull, NCDFError, CachedOrNull }; - Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); - oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); + Klass* as_klass(Handle class_loader, FailureMode failure_mode, TRAPS); + oop as_java_mirror(Handle class_loader, FailureMode failure_mode, TRAPS); }; // Specialized SignatureStream: used for invoking SystemDictionary to either find @@ -573,7 +573,6 @@ class ResolvingSignatureStream : public SignatureStream { Klass* _load_origin; bool _handles_cached; Handle _class_loader; // cached when needed - Handle _protection_domain; // cached when needed void initialize_load_origin(Klass* load_origin) { _load_origin = load_origin; @@ -589,20 +588,18 @@ class ResolvingSignatureStream : public SignatureStream { public: ResolvingSignatureStream(Symbol* signature, Klass* load_origin, bool is_method = true); - ResolvingSignatureStream(Symbol* signature, Handle class_loader, Handle protection_domain, bool is_method = true); + ResolvingSignatureStream(Symbol* signature, Handle class_loader, bool is_method = true); ResolvingSignatureStream(const Method* method); Klass* as_klass(FailureMode failure_mode, TRAPS) { need_handles(); - return SignatureStream::as_klass(_class_loader, _protection_domain, - failure_mode, THREAD); + return SignatureStream::as_klass(_class_loader, failure_mode, THREAD); } oop as_java_mirror(FailureMode failure_mode, TRAPS) { if (is_reference()) { need_handles(); } - return SignatureStream::as_java_mirror(_class_loader, _protection_domain, - failure_mode, THREAD); + return SignatureStream::as_java_mirror(_class_loader, failure_mode, THREAD); } }; diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 41ac7bc6627..f6b7b7956e2 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -385,7 +385,7 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { // Some values are actually configure-time constants but some can be set via the jlink tool and // so must be read dynamically. We treat them all the same. InstanceKlass* ik = SystemDictionary::find_instance_klass(THREAD, vmSymbols::java_lang_VersionProps(), - Handle(), Handle()); + Handle()); { ResourceMark rm(main_thread); JDK_Version::set_java_version(get_java_version_info(ik, vmSymbols::java_version_name())); diff --git a/src/hotspot/share/runtime/vframe.cpp b/src/hotspot/share/runtime/vframe.cpp index 41a46c86a70..fbf82c69673 100644 --- a/src/hotspot/share/runtime/vframe.cpp +++ b/src/hotspot/share/runtime/vframe.cpp @@ -532,8 +532,7 @@ vframeStream::vframeStream(oop continuation, Handle continuation_scope) // Step back n frames, skip any pseudo frames in between. -// This function is used in Class.forName, Class.newInstance, Method.Invoke, -// AccessController.doPrivileged. +// This function is used in Class.forName, Class.newInstance, and Method.Invoke. void vframeStreamCommon::security_get_caller_frame(int depth) { assert(depth >= 0, "invalid depth: %d", depth); for (int n = 0; !at_end(); security_next()) { diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index ac711520065..240f3604cc1 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -695,7 +695,7 @@ void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_VOID); @@ -768,7 +768,7 @@ void JMXStartLocalDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_VOID); JavaCalls::call_static(&result, k, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK); @@ -785,7 +785,7 @@ void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_VOID); JavaCalls::call_static(&result, k, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK); @@ -806,7 +806,7 @@ void JMXStatusDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_OBJECT); JavaCalls::call_static(&result, k, vmSymbols::getAgentStatus_name(), vmSymbols::void_string_signature(), CHECK); diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index ac7e1daf397..7729fb08808 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -160,7 +160,6 @@ void Management::initialize(TRAPS) { Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_agent_Agent(), loader, - Handle(), THREAD); if (k == nullptr) { vm_exit_during_initialization("Management agent initialization failure: " diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index 10405a06048..0f87f76a2e8 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -188,30 +188,30 @@ void Exceptions::_throw(JavaThread* thread, const char* file, int line, Handle h void Exceptions::_throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { // Check for special boot-strapping/compiler-thread handling if (special_exception(thread, file, line, Handle(), name, message)) return; // Create and throw exception Handle h_cause(thread, nullptr); - Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader); _throw(thread, file, line, h_exception, message); } void Exceptions::_throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { // Check for special boot-strapping/compiler-thread handling if (special_exception(thread, file, line, Handle(), name, message)) return; // Create and throw exception and init cause - Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader); _throw(thread, file, line, h_exception, message); } void Exceptions::_throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { // Check for special boot-strapping/compiler-thread handling if (special_exception(thread, file, line, Handle(), name)) return; // Create and throw exception - Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, h_cause, h_loader); _throw(thread, file, line, h_exception, nullptr); } @@ -229,13 +229,13 @@ void Exceptions::_throw_args(JavaThread* thread, const char* file, int line, Sym // Methods for default parameters. // NOTE: These must be here (and not in the header file) because of include circularities. void Exceptions::_throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) { - _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, nullptr), Handle(thread, nullptr)); + _throw_msg_cause(thread, file, line, name, message, h_cause, Handle()); } void Exceptions::_throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message) { - _throw_msg(thread, file, line, name, message, Handle(thread, nullptr), Handle(thread, nullptr)); + _throw_msg(thread, file, line, name, message, Handle()); } void Exceptions::_throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause) { - _throw_cause(thread, file, line, name, h_cause, Handle(thread, nullptr), Handle(thread, nullptr)); + _throw_cause(thread, file, line, name, h_cause, Handle()); } @@ -297,7 +297,7 @@ void Exceptions::fthrow(JavaThread* thread, const char* file, int line, Symbol* // and returns a Handle Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments *args, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { assert(Universe::is_fully_initialized(), "cannot be called during initialization"); assert(!thread->has_pending_exception(), "already has exception"); @@ -305,7 +305,7 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Handle h_exception; // Resolve exception klass, and check for pending exception below. - Klass* klass = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread); + Klass* klass = SystemDictionary::resolve_or_fail(name, h_loader, true, thread); if (!thread->has_pending_exception()) { assert(klass != nullptr, "klass must exist"); @@ -329,8 +329,8 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments *args, Handle h_cause, - Handle h_loader, Handle h_protection_domain) { - Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain); + Handle h_loader) { + Handle h_exception = new_exception(thread, name, signature, args, h_loader); // Future: object initializer should take a cause argument if (h_cause.not_null()) { @@ -359,7 +359,7 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, // creating a new exception Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Handle h_cause, - Handle h_loader, Handle h_protection_domain, + Handle h_loader, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; Symbol* signature = nullptr; @@ -369,14 +369,14 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, signature = vmSymbols::throwable_void_signature(); args.push_oop(h_cause); } - return new_exception(thread, name, signature, &args, h_loader, h_protection_domain); + return new_exception(thread, name, signature, &args, h_loader); } // Convenience method. Calls either the () or (String) method when // creating a new exception Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, Handle h_protection_domain, + Handle h_loader, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; Symbol* signature = nullptr; @@ -413,11 +413,10 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, args.push_oop(msg); signature = vmSymbols::string_void_signature(); } - return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain); + return new_exception(thread, name, signature, &args, h_cause, h_loader); } -// Another convenience method that creates handles for null class loaders and -// protection domains and null causes. +// Another convenience method that creates handles for null class loaders and null causes. // If the last parameter 'to_utf8_mode' is safe_to_utf8, // it means we can safely ignore the encoding scheme of the message string and // convert it directly to a java UTF8 string. Otherwise, we need to take the @@ -428,11 +427,10 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, const char* message, ExceptionMsgToUtf8Mode to_utf8_safe) { - Handle h_loader(thread, nullptr); - Handle h_prot(thread, nullptr); - Handle h_cause(thread, nullptr); + Handle h_loader; + Handle h_cause; return Exceptions::new_exception(thread, name, message, h_cause, h_loader, - h_prot, to_utf8_safe); + to_utf8_safe); } // invokedynamic uses wrap_dynamic_exception for: diff --git a/src/hotspot/share/utilities/exceptions.hpp b/src/hotspot/share/utilities/exceptions.hpp index 33eba68d6d9..0dca7971ef9 100644 --- a/src/hotspot/share/utilities/exceptions.hpp +++ b/src/hotspot/share/utilities/exceptions.hpp @@ -128,15 +128,15 @@ class Exceptions { static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message); static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, - Handle loader, Handle protection_domain); + Handle loader); static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause); static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, Handle h_protection_domain); + Handle h_loader); static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause); static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause, - Handle h_loader, Handle h_protection_domain); + Handle h_loader); static void _throw_args(JavaThread* thread, const char* file, int line, Symbol* name, Symbol* signature, @@ -150,21 +150,21 @@ class Exceptions { // Create and initialize a new exception static Handle new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments* args, - Handle loader, Handle protection_domain); + Handle loader); static Handle new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments* args, Handle cause, - Handle loader, Handle protection_domain); + Handle loader); static Handle new_exception(JavaThread* thread, Symbol* name, Handle cause, - Handle loader, Handle protection_domain, + Handle loader, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); static Handle new_exception(JavaThread* thread, Symbol* name, const char* message, Handle cause, - Handle loader, Handle protection_domain, + Handle loader, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); static Handle new_exception(JavaThread* thread, Symbol* name, @@ -268,8 +268,8 @@ class Exceptions { #define THROW_CAUSE(name, cause) \ { Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; } -#define THROW_MSG_LOADER(name, message, loader, protection_domain) \ - { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return; } +#define THROW_MSG_LOADER(name, message, loader) \ + { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader); return; } #define THROW_ARG(name, signature, args) \ { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return; } @@ -286,8 +286,8 @@ class Exceptions { #define THROW_MSG_(name, message, result) \ { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return result; } -#define THROW_MSG_LOADER_(name, message, loader, protection_domain, result) \ - { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return result; } +#define THROW_MSG_LOADER_(name, message, loader, result) \ + { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader); return result; } #define THROW_ARG_(name, signature, args, result) \ { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; } diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index ba1851708b2..d3de1f871e8 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -113,9 +113,6 @@ runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433 macosx-x64 runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x64 -runtime/Dictionary/CleanProtectionDomain.java 8341916 generic-all -runtime/Dictionary/ProtectionDomainCacheTest.java 8341916 generic-all -runtime/logging/ProtectionDomainVerificationTest.java 8341916 generic-all runtime/NMT/VirtualAllocCommitMerge.java 8309698 linux-s390x # Fails with +UseCompactObjectHeaders on aarch64 diff --git a/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java b/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java deleted file mode 100644 index 4e4a9329f5d..00000000000 --- a/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary Verifies the creation and cleaup of entries in the Protection Domain Table - * @requires vm.flagless - * @library /test/lib - * @modules java.base/jdk.internal.misc - * @build jdk.test.whitebox.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run driver CleanProtectionDomain - */ - -import java.security.ProtectionDomain; -import jdk.test.lib.compiler.InMemoryJavaCompiler; -import jdk.internal.misc.Unsafe; -import static jdk.test.lib.Asserts.*; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; -import jdk.test.whitebox.WhiteBox; - -public class CleanProtectionDomain { - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-Xlog:protectiondomain+table=debug", - "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "-Xbootclasspath/a:.", - "-Djava.security.manager=allow", - Test.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("protection domain added"); - output.shouldContain("protection domain unlinked"); - output.shouldHaveExitValue(0); - } - - static class Test { - public static void test() throws Exception { - TestClassLoader classloader = new TestClassLoader(); - ProtectionDomain pd = new ProtectionDomain(null, null); - byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass", "class TestClass { }"); - Class klass = classloader.defineClass("TestClass", klassbuf, pd); - } - - public static void main(String[] args) throws Exception { - WhiteBox wb = WhiteBox.getWhiteBox(); - int removedCountOrig = wb.protectionDomainRemovedCount(); - int removedCount; - - test(); - - // Wait until ServiceThread cleans ProtectionDomain table. - // When the TestClassLoader is unloaded by GC, at least one - // ProtectionDomainCacheEntry will be eligible for removal. - int cnt = 0; - while (true) { - if (cnt++ % 30 == 0) { - System.gc(); - } - removedCount = wb.protectionDomainRemovedCount(); - if (removedCountOrig != removedCount) { - break; - } - Thread.sleep(100); - } - } - - private static class TestClassLoader extends ClassLoader { - public TestClassLoader() { - super(); - } - - public Class defineClass(String name, byte[] bytes, ProtectionDomain pd) { - return defineClass(name, bytes, 0, bytes.length, pd); - } - } - } -} diff --git a/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java b/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java deleted file mode 100644 index 423fba7d221..00000000000 --- a/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8151486 8218266 - * @summary Call Class.forName() on the system classloader from a class loaded - * from a custom classloader, using the current class's protection domain. - * @requires vm.flagless - * @library /test/lib - * @modules java.base/jdk.internal.misc - * @build jdk.test.lib.Utils - * jdk.test.lib.util.JarUtils - * @build ClassForName ProtectionDomainCacheTest - * @run driver ProtectionDomainCacheTest - */ - -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import jdk.test.lib.Utils; -import jdk.test.lib.util.JarUtils; -import java.io.File; - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; - -/* - * Create .jar, load ClassForName from .jar using a URLClassLoader - */ -public class ProtectionDomainCacheTest { - static class Test { - private static final long TIMEOUT = (long)(5000.0 * Utils.TIMEOUT_FACTOR); - private static final String TESTCLASSES = System.getProperty("test.classes", "."); - private static final String CLASSFILENAME = "ClassForName.class"; - - // Use a new classloader to load the ClassForName class. - public static void loadAndRun(Path jarFilePath) - throws Exception { - ClassLoader classLoader = new URLClassLoader( - new URL[]{jarFilePath.toUri().toURL()}) { - @Override public String toString() { return "LeakedClassLoader"; } - }; - - Class loadClass = Class.forName("ClassForName", true, classLoader); - loadClass.newInstance(); - - System.out.println("returning : " + classLoader); - } - - public static void main(final String[] args) throws Exception { - // Create a temporary .jar file containing ClassForName.class - Path testClassesDir = Paths.get(TESTCLASSES); - Path jarFilePath = Files.createTempFile("cfn", ".jar"); - JarUtils.createJarFile(jarFilePath, testClassesDir, CLASSFILENAME); - jarFilePath.toFile().deleteOnExit(); - - // Remove the ClassForName.class file that jtreg built, to make sure - // we're loading from the tmp .jar - Path classFile = FileSystems.getDefault().getPath(TESTCLASSES, - CLASSFILENAME); - Files.delete(classFile); - - for (int i = 0; i < 20; i++) { - loadAndRun(jarFilePath); - } - - // Give the GC a chance to unload protection domains - for (int i = 0; i < 100; i++) { - System.gc(); - } - System.out.println("All Classloaders and protection domain cache entries successfully unloaded"); - } - } - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-Djava.security.policy==" + System.getProperty("test.src") + File.separator + "test.policy", - "-Dtest.classes=" + System.getProperty("test.classes", "."), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:VerifySubSet=dictionary", - "-XX:+VerifyAfterGC", - "-Xlog:gc+verify,protectiondomain=trace", - "-Djava.security.manager", - Test.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("PD in set is not alive"); - output.shouldContain("HandshakeForPD::do_thread"); - output.shouldHaveExitValue(0); - } -} diff --git a/test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java b/test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java deleted file mode 100644 index e8e5c881125..00000000000 --- a/test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test ProtectionDomainVerificationTest - * @bug 8149064 - * @requires vm.flagless - * @modules java.base/jdk.internal.misc - * @library /test/lib - * @run driver ProtectionDomainVerificationTest - */ - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Platform; -import jdk.test.lib.process.ProcessTools; - -public class ProtectionDomainVerificationTest { - - public static void main(String... args) throws Exception { - - // -Xlog:protectiondomain=trace - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:protectiondomain=trace", - "-Xmx128m", - "-Djava.security.manager=allow", - Hello.class.getName(), "security_manager"); - new OutputAnalyzer(pb.start()) - .shouldHaveExitValue(0) - .shouldContain("[protectiondomain] Checking package access") - .shouldContain("[protectiondomain] adding protection domain that can access class"); - - // -Xlog:protectiondomain=debug - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:protectiondomain=debug", - "-Xmx128m", - "-Djava.security.manager=allow", - Hello.class.getName(), "security_manager"); - new OutputAnalyzer(pb.start()) - .shouldHaveExitValue(0) - .shouldContain("[protectiondomain] Checking package access") - .shouldNotContain("[protectiondomain] adding protection domain that can access class"); - - // -Xlog:protectiondomain=debug - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:protectiondomain=trace", - "-Xmx128m", - "-Djava.security.manager=disallow", - Hello.class.getName()); - new OutputAnalyzer(pb.start()) - .shouldHaveExitValue(0) - .shouldNotContain("[protectiondomain] Checking package access") - .shouldNotContain("pd set count = #"); - } - - public static class Hello { - public static void main(String[] args) { - if (args.length == 1) { - // Need a security manager to trigger logging. - System.setSecurityManager(new SecurityManager()); - } - System.out.print("Hello!"); - } - } -} diff --git a/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java b/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java index 29223efb8ee..50b6b53233e 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,14 +67,6 @@ public class DictionaryStatsTest { // Variance of bucket size : 0.281 // Std. dev. of bucket size: 0.530 // Maximum bucket size : 2 - // ProtectionDomainCacheTable statistics: - // Number of buckets : 1009 = 8072 bytes, each 8 - // Number of entries : 0 = 0 bytes, each 0 - // Total footprint : = 8072 bytes - // Average bucket size : 0.000 - // Variance of bucket size : 0.000 - // Std. dev. of bucket size: 0.000 - // Maximum bucket size : 0 public void run(CommandExecutor executor) throws ClassNotFoundException { @@ -99,10 +91,6 @@ public class DictionaryStatsTest { output.shouldContain("Std. dev. of bucket size"); output.shouldContain("Maximum bucket size"); output.shouldMatch("LoaderConstraintTable statistics:"); - // Would be nice to run this with "-Djava.security.manager=allow" - // so the numbers aren't 0 (running make with VM_OPTIONS allowing - // security manager does get 12 entries in this table.) - output.shouldMatch("ProtectionDomainCacheTable statistics:"); // what is this? Reference.reachabilityFence(named_cl); diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 0db7c46c6cf..2e723d91267 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -776,9 +776,6 @@ public class WhiteBox { // Resolved Method Table public native long resolvedMethodItemsCount(); - // Protection Domain Table - public native int protectionDomainRemovedCount(); - public native int getKlassMetadataSize(Class c); // ThreadSMR GC safety check for threadObj