Path: blob/master/src/hotspot/share/classfile/dictionary.cpp
40949 views
/*1* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/classLoaderData.inline.hpp"26#include "classfile/dictionary.hpp"27#include "classfile/javaClasses.hpp"28#include "classfile/protectionDomainCache.hpp"29#include "classfile/systemDictionary.hpp"30#include "classfile/vmSymbols.hpp"31#include "logging/log.hpp"32#include "logging/logStream.hpp"33#include "memory/iterator.hpp"34#include "memory/metaspaceClosure.hpp"35#include "memory/resourceArea.hpp"36#include "memory/universe.hpp"37#include "oops/klass.inline.hpp"38#include "oops/method.hpp"39#include "oops/oop.inline.hpp"40#include "oops/oopHandle.inline.hpp"41#include "runtime/arguments.hpp"42#include "runtime/handles.inline.hpp"43#include "runtime/javaCalls.hpp"44#include "runtime/mutexLocker.hpp"45#include "runtime/safepointVerifiers.hpp"46#include "utilities/growableArray.hpp"47#include "utilities/hashtable.inline.hpp"4849// Optimization: if any dictionary needs resizing, we set this flag,50// so that we dont't have to walk all dictionaries to check if any actually51// needs resizing, which is costly to do at Safepoint.52bool Dictionary::_some_dictionary_needs_resizing = false;5354Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable)55: Hashtable<InstanceKlass*, mtClass>(table_size, (int)sizeof(DictionaryEntry)),56_resizable(resizable), _needs_resizing(false), _loader_data(loader_data) {57};585960Dictionary::Dictionary(ClassLoaderData* loader_data,61int table_size, HashtableBucket<mtClass>* t,62int number_of_entries, bool resizable)63: Hashtable<InstanceKlass*, mtClass>(table_size, (int)sizeof(DictionaryEntry), t, number_of_entries),64_resizable(resizable), _needs_resizing(false), _loader_data(loader_data) {65};6667Dictionary::~Dictionary() {68DictionaryEntry* probe = NULL;69for (int index = 0; index < table_size(); index++) {70for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {71probe = *p;72*p = probe->next();73free_entry(probe);74}75}76assert(number_of_entries() == 0, "should have removed all entries");77}7879DictionaryEntry* Dictionary::new_entry(unsigned int hash, InstanceKlass* klass) {80DictionaryEntry* entry = (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);81entry->release_set_pd_set(NULL);82assert(klass->is_instance_klass(), "Must be");83return entry;84}8586void Dictionary::free_entry(DictionaryEntry* entry) {87// avoid recursion when deleting linked list88// pd_set is accessed during a safepoint.89// This doesn't require a lock because nothing is reading this90// entry anymore. The ClassLoader is dead.91while (entry->pd_set_acquire() != NULL) {92ProtectionDomainEntry* to_delete = entry->pd_set_acquire();93entry->release_set_pd_set(to_delete->next_acquire());94delete to_delete;95}96BasicHashtable<mtClass>::free_entry(entry);97}9899const int _resize_load_trigger = 5; // load factor that will trigger the resize100101bool Dictionary::does_any_dictionary_needs_resizing() {102return Dictionary::_some_dictionary_needs_resizing;103}104105void Dictionary::check_if_needs_resize() {106if (_resizable == true) {107if (number_of_entries() > (_resize_load_trigger*table_size())) {108_needs_resizing = true;109Dictionary::_some_dictionary_needs_resizing = true;110}111}112}113114bool Dictionary::resize_if_needed() {115assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");116int desired_size = 0;117if (_needs_resizing == true) {118desired_size = calculate_resize(false);119assert(desired_size != 0, "bug in calculate_resize");120if (desired_size == table_size()) {121_resizable = false; // hit max122} else {123if (!resize(desired_size)) {124// Something went wrong, turn resizing off125_resizable = false;126}127}128}129130_needs_resizing = false;131Dictionary::_some_dictionary_needs_resizing = false;132133return (desired_size != 0);134}135136bool DictionaryEntry::is_valid_protection_domain(Handle protection_domain) {137138return protection_domain() == NULL || !java_lang_System::allow_security_manager()139? true140: contains_protection_domain(protection_domain());141}142143// Reading the pd_set on each DictionaryEntry is lock free and cannot safepoint.144// Adding and deleting entries is under the SystemDictionary_lock145// Deleting unloaded entries on ClassLoaderData for dictionaries that are not unloaded146// is a three step process:147// moving the entries to a separate list, handshake to wait for148// readers to complete (see NSV here), and then actually deleting the entries.149// Deleting entries is done by the ServiceThread when triggered by class unloading.150151bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {152assert(Thread::current()->is_Java_thread() || SafepointSynchronize::is_at_safepoint(),153"can only be called by a JavaThread or at safepoint");154// This cannot safepoint while reading the protection domain set.155NoSafepointVerifier nsv;156#ifdef ASSERT157if (protection_domain == instance_klass()->protection_domain()) {158// Ensure this doesn't show up in the pd_set (invariant)159bool in_pd_set = false;160for (ProtectionDomainEntry* current = pd_set_acquire();161current != NULL;162current = current->next_acquire()) {163if (current->object_no_keepalive() == protection_domain) {164in_pd_set = true;165break;166}167}168if (in_pd_set) {169assert(false, "A klass's protection domain should not show up "170"in its sys. dict. PD set");171}172}173#endif /* ASSERT */174175if (protection_domain == instance_klass()->protection_domain()) {176// Succeeds trivially177return true;178}179180for (ProtectionDomainEntry* current = pd_set_acquire();181current != NULL;182current = current->next_acquire()) {183if (current->object_no_keepalive() == protection_domain) {184return true;185}186}187return false;188}189190void DictionaryEntry::add_protection_domain(ClassLoaderData* loader_data, Handle protection_domain) {191assert_lock_strong(SystemDictionary_lock);192if (!contains_protection_domain(protection_domain())) {193ProtectionDomainCacheEntry* entry = SystemDictionary::pd_cache_table()->get(protection_domain);194// Additions and deletions hold the SystemDictionary_lock, readers are lock-free195ProtectionDomainEntry* new_head = new ProtectionDomainEntry(entry, _pd_set);196release_set_pd_set(new_head);197}198LogTarget(Trace, protectiondomain) lt;199if (lt.is_enabled()) {200ResourceMark rm;201LogStream ls(lt);202ls.print("adding protection domain for class %s", instance_klass()->name()->as_C_string());203ls.print(" class loader: ");204loader_data->class_loader()->print_value_on(&ls);205ls.print(" protection domain: ");206protection_domain->print_value_on(&ls);207ls.print(" ");208print_count(&ls);209ls.cr();210}211}212213// Just the classes from defining class loaders214void Dictionary::classes_do(void f(InstanceKlass*)) {215for (int index = 0; index < table_size(); index++) {216for (DictionaryEntry* probe = bucket(index);217probe != NULL;218probe = probe->next()) {219InstanceKlass* k = probe->instance_klass();220if (loader_data() == k->class_loader_data()) {221f(k);222}223}224}225}226227// Added for initialize_itable_for_klass to handle exceptions228// Just the classes from defining class loaders229void Dictionary::classes_do(void f(InstanceKlass*, TRAPS), TRAPS) {230for (int index = 0; index < table_size(); index++) {231for (DictionaryEntry* probe = bucket(index);232probe != NULL;233probe = probe->next()) {234InstanceKlass* k = probe->instance_klass();235if (loader_data() == k->class_loader_data()) {236f(k, CHECK);237}238}239}240}241242// All classes, and their class loaders, including initiating class loaders243void Dictionary::all_entries_do(KlassClosure* closure) {244for (int index = 0; index < table_size(); index++) {245for (DictionaryEntry* probe = bucket(index);246probe != NULL;247probe = probe->next()) {248InstanceKlass* k = probe->instance_klass();249closure->do_klass(k);250}251}252}253254// Used to scan and relocate the classes during CDS archive dump.255void Dictionary::classes_do(MetaspaceClosure* it) {256Arguments::assert_is_dumping_archive();257for (int index = 0; index < table_size(); index++) {258for (DictionaryEntry* probe = bucket(index);259probe != NULL;260probe = probe->next()) {261it->push(probe->klass_addr());262}263}264}265266267268// Add a loaded class to the dictionary.269// Readers of the SystemDictionary aren't always locked, so _buckets270// is volatile. The store of the next field in the constructor is271// also cast to volatile; we do this to ensure store order is maintained272// by the compilers.273274void Dictionary::add_klass(unsigned int hash, Symbol* class_name,275InstanceKlass* obj) {276assert_locked_or_safepoint(SystemDictionary_lock);277assert(obj != NULL, "adding NULL obj");278assert(obj->name() == class_name, "sanity check on name");279280DictionaryEntry* entry = new_entry(hash, obj);281int index = hash_to_index(hash);282add_entry(index, entry);283check_if_needs_resize();284}285286287// This routine does not lock the dictionary.288//289// Since readers don't hold a lock, we must make sure that system290// dictionary entries are only removed at a safepoint (when only one291// thread is running), and are added to in a safe way (all links must292// be updated in an MT-safe manner).293//294// Callers should be aware that an entry could be added just after295// _buckets[index] is read here, so the caller will not see the new entry.296DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,297Symbol* class_name) {298for (DictionaryEntry* entry = bucket(index);299entry != NULL;300entry = entry->next()) {301if (entry->hash() == hash && entry->instance_klass()->name() == class_name) {302return entry;303}304}305return NULL;306}307308309310InstanceKlass* Dictionary::find(unsigned int hash, Symbol* name,311Handle protection_domain) {312NoSafepointVerifier nsv;313314int index = hash_to_index(hash);315DictionaryEntry* entry = get_entry(index, hash, name);316if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {317return entry->instance_klass();318} else {319return NULL;320}321}322323InstanceKlass* Dictionary::find_class(unsigned int hash,324Symbol* name) {325assert_locked_or_safepoint(SystemDictionary_lock);326327int index = hash_to_index(hash);328assert (index == index_for(name), "incorrect index?");329330DictionaryEntry* entry = get_entry(index, hash, name);331return (entry != NULL) ? entry->instance_klass() : NULL;332}333334void Dictionary::add_protection_domain(int index, unsigned int hash,335InstanceKlass* klass,336Handle protection_domain) {337assert(java_lang_System::allow_security_manager(), "only needed if security manager allowed");338Symbol* klass_name = klass->name();339DictionaryEntry* entry = get_entry(index, hash, klass_name);340341assert(entry != NULL,"entry must be present, we just created it");342assert(protection_domain() != NULL,343"real protection domain should be present");344345entry->add_protection_domain(loader_data(), protection_domain);346347#ifdef ASSERT348assert(loader_data() != ClassLoaderData::the_null_class_loader_data(), "doesn't make sense");349#endif350351assert(entry->contains_protection_domain(protection_domain()),352"now protection domain should be present");353}354355356inline bool Dictionary::is_valid_protection_domain(unsigned int hash,357Symbol* name,358Handle protection_domain) {359int index = hash_to_index(hash);360DictionaryEntry* entry = get_entry(index, hash, name);361return entry->is_valid_protection_domain(protection_domain);362}363364void Dictionary::validate_protection_domain(unsigned int name_hash,365InstanceKlass* klass,366Handle class_loader,367Handle protection_domain,368TRAPS) {369370assert(class_loader() != NULL, "Should not call this");371assert(protection_domain() != NULL, "Should not call this");372373if (!java_lang_System::allow_security_manager() ||374is_valid_protection_domain(name_hash, klass->name(), protection_domain)) {375return;376}377378// We only have to call checkPackageAccess if there's a security manager installed.379if (java_lang_System::has_security_manager()) {380381// This handle and the class_loader handle passed in keeps this class from382// being unloaded through several GC points.383// The class_loader handle passed in is the initiating loader.384Handle mirror(THREAD, klass->java_mirror());385386// Now we have to call back to java to check if the initating class has access387InstanceKlass* system_loader = vmClasses::ClassLoader_klass();388JavaValue result(T_VOID);389JavaCalls::call_special(&result,390class_loader,391system_loader,392vmSymbols::checkPackageAccess_name(),393vmSymbols::class_protectiondomain_signature(),394mirror,395protection_domain,396THREAD);397398LogTarget(Debug, protectiondomain) lt;399if (lt.is_enabled()) {400ResourceMark rm(THREAD);401// Print out trace information402LogStream ls(lt);403ls.print_cr("Checking package access");404ls.print("class loader: ");405class_loader()->print_value_on(&ls);406ls.print(" protection domain: ");407protection_domain()->print_value_on(&ls);408ls.print(" loading: "); klass->print_value_on(&ls);409if (HAS_PENDING_EXCEPTION) {410ls.print_cr(" DENIED !!!!!!!!!!!!!!!!!!!!!");411} else {412ls.print_cr(" granted");413}414}415416if (HAS_PENDING_EXCEPTION) return;417}418419// If no exception has been thrown, we have validated the protection domain420// Insert the protection domain of the initiating class into the set.421// We still have to add the protection_domain to the dictionary in case a new422// security manager is installed later. Calls to load the same class with class loader423// and protection domain are expected to succeed.424{425MutexLocker mu(THREAD, SystemDictionary_lock);426int d_index = hash_to_index(name_hash);427add_protection_domain(d_index, name_hash, klass,428protection_domain);429}430}431432// During class loading we may have cached a protection domain that has433// since been unreferenced, so this entry should be cleared.434void Dictionary::clean_cached_protection_domains(GrowableArray<ProtectionDomainEntry*>* delete_list) {435assert(Thread::current()->is_Java_thread(), "only called by JavaThread");436assert_lock_strong(SystemDictionary_lock);437assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder");438439if (loader_data()->is_the_null_class_loader_data()) {440// Classes in the boot loader are not loaded with protection domains441return;442}443444for (int index = 0; index < table_size(); index++) {445for (DictionaryEntry* probe = bucket(index);446probe != NULL;447probe = probe->next()) {448Klass* e = probe->instance_klass();449450ProtectionDomainEntry* current = probe->pd_set_acquire();451ProtectionDomainEntry* prev = NULL;452while (current != NULL) {453if (current->object_no_keepalive() == NULL) {454LogTarget(Debug, protectiondomain) lt;455if (lt.is_enabled()) {456ResourceMark rm;457// Print out trace information458LogStream ls(lt);459ls.print_cr("PD in set is not alive:");460ls.print("class loader: "); loader_data()->class_loader()->print_value_on(&ls);461ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls);462ls.cr();463}464if (probe->pd_set_acquire() == current) {465probe->release_set_pd_set(current->next_acquire());466} else {467assert(prev != NULL, "should be set by alive entry");468prev->release_set_next(current->next_acquire());469}470// Mark current for deletion but in the meantime it can still be471// traversed.472delete_list->push(current);473current = current->next_acquire();474} else {475prev = current;476current = current->next_acquire();477}478}479}480}481}482483oop SymbolPropertyEntry::method_type() const {484return _method_type.resolve();485}486487void SymbolPropertyEntry::set_method_type(oop p) {488_method_type = OopHandle(Universe::vm_global(), p);489}490491void SymbolPropertyEntry::free_entry() {492// decrement Symbol refcount here because hashtable doesn't.493literal()->decrement_refcount();494// Free OopHandle495_method_type.release(Universe::vm_global());496}497498void SymbolPropertyEntry::print_entry(outputStream* st) const {499symbol()->print_value_on(st);500st->print("/mode=" INTX_FORMAT, symbol_mode());501st->print(" -> ");502bool printed = false;503if (method() != NULL) {504method()->print_value_on(st);505printed = true;506}507if (method_type() != NULL) {508if (printed) st->print(" and ");509st->print(INTPTR_FORMAT, p2i((void *)method_type()));510printed = true;511}512st->print_cr(printed ? "" : "(empty)");513}514515SymbolPropertyTable::SymbolPropertyTable(int table_size)516: Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))517{518}519SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t,520int number_of_entries)521: Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)522{523}524525526SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,527Symbol* sym,528intptr_t sym_mode) {529assert(index == index_for(sym, sym_mode), "incorrect index?");530for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {531if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) {532return p;533}534}535return NULL;536}537538539SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash,540Symbol* sym, intptr_t sym_mode) {541assert_locked_or_safepoint(SystemDictionary_lock);542assert(index == index_for(sym, sym_mode), "incorrect index?");543assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry");544545SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);546Hashtable<Symbol*, mtSymbol>::add_entry(index, p);547return p;548}549550void SymbolPropertyTable::methods_do(void f(Method*)) {551for (int index = 0; index < table_size(); index++) {552for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {553Method* prop = p->method();554if (prop != NULL) {555f((Method*)prop);556}557}558}559}560561void SymbolPropertyTable::free_entry(SymbolPropertyEntry* entry) {562entry->free_entry();563BasicHashtable<mtSymbol>::free_entry(entry);564}565566void DictionaryEntry::verify_protection_domain_set() {567assert(SafepointSynchronize::is_at_safepoint(), "must only be called as safepoint");568for (ProtectionDomainEntry* current = pd_set_acquire(); // accessed at a safepoint569current != NULL;570current = current->next_acquire()) {571guarantee(oopDesc::is_oop_or_null(current->object_no_keepalive()), "Invalid oop");572}573}574575void DictionaryEntry::print_count(outputStream *st) {576assert_locked_or_safepoint(SystemDictionary_lock);577int count = 0;578for (ProtectionDomainEntry* current = pd_set_acquire();579current != NULL;580current = current->next_acquire()) {581count++;582}583st->print("pd set count = #%d", count);584}585586// ----------------------------------------------------------------------------587588void Dictionary::print_on(outputStream* st) const {589ResourceMark rm;590591assert(loader_data() != NULL, "loader data should not be null");592assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder");593st->print_cr("Java dictionary (table_size=%d, classes=%d, resizable=%s)",594table_size(), number_of_entries(), BOOL_TO_STR(_resizable));595st->print_cr("^ indicates that initiating loader is different from defining loader");596597for (int index = 0; index < table_size(); index++) {598for (DictionaryEntry* probe = bucket(index);599probe != NULL;600probe = probe->next()) {601Klass* e = probe->instance_klass();602bool is_defining_class =603(loader_data() == e->class_loader_data());604st->print("%4d: %s%s", index, is_defining_class ? " " : "^", e->external_name());605ClassLoaderData* cld = e->class_loader_data();606if (!loader_data()->is_the_null_class_loader_data()) {607// Class loader output for the dictionary for the null class loader data is608// redundant and obvious.609st->print(", ");610cld->print_value_on(st);611st->print(", ");612probe->print_count(st);613}614st->cr();615}616}617tty->cr();618}619620void DictionaryEntry::verify() {621Klass* e = instance_klass();622guarantee(e->is_instance_klass(),623"Verify of dictionary failed");624e->verify();625verify_protection_domain_set();626}627628void Dictionary::verify() {629guarantee(number_of_entries() >= 0, "Verify of dictionary failed");630631ClassLoaderData* cld = loader_data();632// class loader must be present; a null class loader is the633// boostrap loader634guarantee(cld != NULL &&635(cld->the_null_class_loader_data() || cld->class_loader()->is_instance()),636"checking type of class_loader");637638ResourceMark rm;639stringStream tempst;640tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());641verify_table<DictionaryEntry>(tempst.as_string());642}643644645