Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/dictionary.cpp
32285 views
/*1* Copyright (c) 2003, 2018, 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/dictionary.hpp"26#include "classfile/systemDictionary.hpp"27#include "classfile/systemDictionaryShared.hpp"28#include "memory/iterator.hpp"29#include "oops/oop.inline.hpp"30#include "prims/jvmtiRedefineClassesTrace.hpp"31#include "runtime/orderAccess.inline.hpp"32#include "utilities/hashtable.inline.hpp"3334PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC3536DictionaryEntry* Dictionary::_current_class_entry = NULL;37int Dictionary::_current_class_index = 0;3839size_t Dictionary::entry_size() {40if (DumpSharedSpaces) {41return SystemDictionaryShared::dictionary_entry_size();42} else {43return sizeof(DictionaryEntry);44}45}4647Dictionary::Dictionary(int table_size)48: TwoOopHashtable<Klass*, mtClass>(table_size, (int)entry_size()) {49_current_class_index = 0;50_current_class_entry = NULL;51_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);52};535455Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,56int number_of_entries)57: TwoOopHashtable<Klass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {58_current_class_index = 0;59_current_class_entry = NULL;60_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);61};6263ProtectionDomainCacheEntry* Dictionary::cache_get(oop protection_domain) {64return _pd_cache_table->get(protection_domain);65}6667DictionaryEntry* Dictionary::new_entry(unsigned int hash, Klass* klass,68ClassLoaderData* loader_data) {69DictionaryEntry* entry = (DictionaryEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass);70entry->set_loader_data(loader_data);71entry->set_pd_set(NULL);72assert(klass->oop_is_instance(), "Must be");73if (DumpSharedSpaces) {74SystemDictionaryShared::init_shared_dictionary_entry(klass, entry);75}76return entry;77}787980void Dictionary::free_entry(DictionaryEntry* entry) {81// avoid recursion when deleting linked list82while (entry->pd_set() != NULL) {83ProtectionDomainEntry* to_delete = entry->pd_set();84entry->set_pd_set(to_delete->next());85delete to_delete;86}87Hashtable<Klass*, mtClass>::free_entry(entry);88}899091bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {92#ifdef ASSERT93if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) {94// Ensure this doesn't show up in the pd_set (invariant)95bool in_pd_set = false;96for (ProtectionDomainEntry* current = _pd_set;97current != NULL;98current = current->next()) {99if (current->protection_domain() == protection_domain) {100in_pd_set = true;101break;102}103}104if (in_pd_set) {105assert(false, "A klass's protection domain should not show up "106"in its sys. dict. PD set");107}108}109#endif /* ASSERT */110111if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) {112// Succeeds trivially113return true;114}115116for (ProtectionDomainEntry* current = _pd_set;117current != NULL;118current = current->next()) {119if (current->protection_domain() == protection_domain) return true;120}121return false;122}123124125void DictionaryEntry::add_protection_domain(Dictionary* dict, oop protection_domain) {126assert_locked_or_safepoint(SystemDictionary_lock);127if (!contains_protection_domain(protection_domain)) {128ProtectionDomainCacheEntry* entry = dict->cache_get(protection_domain);129ProtectionDomainEntry* new_head =130new ProtectionDomainEntry(entry, _pd_set);131// Warning: Preserve store ordering. The SystemDictionary is read132// without locks. The new ProtectionDomainEntry must be133// complete before other threads can be allowed to see it134// via a store to _pd_set.135OrderAccess::release_store_ptr(&_pd_set, new_head);136}137if (TraceProtectionDomainVerification && WizardMode) {138print();139}140}141142143void Dictionary::do_unloading() {144assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");145146// Remove unloadable entries and classes from system dictionary147// The placeholder array has been handled in always_strong_oops_do.148DictionaryEntry* probe = NULL;149for (int index = 0; index < table_size(); index++) {150for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {151probe = *p;152Klass* e = probe->klass();153ClassLoaderData* loader_data = probe->loader_data();154155InstanceKlass* ik = InstanceKlass::cast(e);156157// Non-unloadable classes were handled in always_strong_oops_do158if (!is_strongly_reachable(loader_data, e)) {159// Entry was not visited in phase1 (negated test from phase1)160assert(!loader_data->is_the_null_class_loader_data(), "unloading entry with null class loader");161162// Do we need to delete this system dictionary entry?163if (loader_data->is_unloading()) {164*p = probe->next();165if (probe == _current_class_entry) {166_current_class_entry = NULL;167}168free_entry(probe);169continue;170}171}172p = probe->next_addr();173}174}175}176177void Dictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {178// Skip the strong roots probe marking if the closures are the same.179if (strong == weak) {180oops_do(strong);181return;182}183184for (int index = 0; index < table_size(); index++) {185for (DictionaryEntry *probe = bucket(index);186probe != NULL;187probe = probe->next()) {188Klass* e = probe->klass();189ClassLoaderData* loader_data = probe->loader_data();190if (is_strongly_reachable(loader_data, e)) {191probe->set_strongly_reachable();192}193}194}195_pd_cache_table->roots_oops_do(strong, weak);196}197198void Dictionary::remove_classes_in_error_state() {199assert(DumpSharedSpaces, "supported only when dumping");200DictionaryEntry* probe = NULL;201for (int index = 0; index < table_size(); index++) {202for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {203probe = *p;204InstanceKlass* ik = InstanceKlass::cast(probe->klass());205if (ik->is_in_error_state()) { // purge this entry206*p = probe->next();207if (probe == _current_class_entry) {208_current_class_entry = NULL;209}210free_entry(probe);211ResourceMark rm;212tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());213continue;214}215216p = probe->next_addr();217}218}219}220221void Dictionary::always_strong_oops_do(OopClosure* blk) {222// Follow all system classes and temporary placeholders in dictionary; only223// protection domain oops contain references into the heap. In a first224// pass over the system dictionary determine which need to be treated as225// strongly reachable and mark them as such.226for (int index = 0; index < table_size(); index++) {227for (DictionaryEntry *probe = bucket(index);228probe != NULL;229probe = probe->next()) {230Klass* e = probe->klass();231ClassLoaderData* loader_data = probe->loader_data();232if (is_strongly_reachable(loader_data, e)) {233probe->set_strongly_reachable();234}235}236}237// Then iterate over the protection domain cache to apply the closure on the238// previously marked ones.239_pd_cache_table->always_strong_oops_do(blk);240}241242243void Dictionary::always_strong_classes_do(KlassClosure* closure) {244// Follow all system classes and temporary placeholders in dictionary245for (int index = 0; index < table_size(); index++) {246for (DictionaryEntry* probe = bucket(index);247probe != NULL;248probe = probe->next()) {249Klass* e = probe->klass();250ClassLoaderData* loader_data = probe->loader_data();251if (is_strongly_reachable(loader_data, e)) {252closure->do_klass(e);253}254}255}256}257258259// Just the classes from defining class loaders260void Dictionary::classes_do(void f(Klass*)) {261for (int index = 0; index < table_size(); index++) {262for (DictionaryEntry* probe = bucket(index);263probe != NULL;264probe = probe->next()) {265Klass* k = probe->klass();266if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) {267f(k);268}269}270}271}272273// Added for initialize_itable_for_klass to handle exceptions274// Just the classes from defining class loaders275void Dictionary::classes_do(void f(Klass*, TRAPS), TRAPS) {276for (int index = 0; index < table_size(); index++) {277for (DictionaryEntry* probe = bucket(index);278probe != NULL;279probe = probe->next()) {280Klass* k = probe->klass();281if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) {282f(k, CHECK);283}284}285}286}287288// All classes, and their class loaders289// Don't iterate over placeholders290void Dictionary::classes_do(void f(Klass*, ClassLoaderData*)) {291for (int index = 0; index < table_size(); index++) {292for (DictionaryEntry* probe = bucket(index);293probe != NULL;294probe = probe->next()) {295Klass* k = probe->klass();296f(k, probe->loader_data());297}298}299}300301void Dictionary::oops_do(OopClosure* f) {302// Only the protection domain oops contain references into the heap. Iterate303// over all of them.304_pd_cache_table->oops_do(f);305}306307void Dictionary::methods_do(void f(Method*)) {308for (int index = 0; index < table_size(); index++) {309for (DictionaryEntry* probe = bucket(index);310probe != NULL;311probe = probe->next()) {312Klass* k = probe->klass();313if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) {314// only take klass is we have the entry with the defining class loader315InstanceKlass::cast(k)->methods_do(f);316}317}318}319}320321void Dictionary::unlink(BoolObjectClosure* is_alive) {322// Only the protection domain cache table may contain references to the heap323// that need to be unlinked.324_pd_cache_table->unlink(is_alive);325}326327Klass* Dictionary::try_get_next_class() {328while (true) {329if (_current_class_entry != NULL) {330Klass* k = _current_class_entry->klass();331_current_class_entry = _current_class_entry->next();332return k;333}334_current_class_index = (_current_class_index + 1) % table_size();335_current_class_entry = bucket(_current_class_index);336}337// never reached338}339340// Add a loaded class to the system dictionary.341// Readers of the SystemDictionary aren't always locked, so _buckets342// is volatile. The store of the next field in the constructor is343// also cast to volatile; we do this to ensure store order is maintained344// by the compilers.345346void Dictionary::add_klass(Symbol* class_name, ClassLoaderData* loader_data,347KlassHandle obj) {348assert_locked_or_safepoint(SystemDictionary_lock);349assert(obj() != NULL, "adding NULL obj");350assert(obj()->name() == class_name, "sanity check on name");351assert(loader_data != NULL, "Must be non-NULL");352353unsigned int hash = compute_hash(class_name, loader_data);354int index = hash_to_index(hash);355DictionaryEntry* entry = new_entry(hash, obj(), loader_data);356add_entry(index, entry);357}358359360// This routine does not lock the system dictionary.361//362// Since readers don't hold a lock, we must make sure that system363// dictionary entries are only removed at a safepoint (when only one364// thread is running), and are added to in a safe way (all links must365// be updated in an MT-safe manner).366//367// Callers should be aware that an entry could be added just after368// _buckets[index] is read here, so the caller will not see the new entry.369DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,370Symbol* class_name,371ClassLoaderData* loader_data) {372debug_only(_lookup_count++);373for (DictionaryEntry* entry = bucket(index);374entry != NULL;375entry = entry->next()) {376if (entry->hash() == hash && entry->equals(class_name, loader_data)) {377return entry;378}379debug_only(_lookup_length++);380}381return NULL;382}383384385Klass* Dictionary::find(int index, unsigned int hash, Symbol* name,386ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {387DictionaryEntry* entry = get_entry(index, hash, name, loader_data);388if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {389return entry->klass();390} else {391return NULL;392}393}394395396Klass* Dictionary::find_class(int index, unsigned int hash,397Symbol* name, ClassLoaderData* loader_data) {398assert_locked_or_safepoint(SystemDictionary_lock);399assert (index == index_for(name, loader_data), "incorrect index?");400401DictionaryEntry* entry = get_entry(index, hash, name, loader_data);402return (entry != NULL) ? entry->klass() : (Klass*)NULL;403}404405406// Variant of find_class for shared classes. No locking required, as407// that table is static.408409Klass* Dictionary::find_shared_class(int index, unsigned int hash,410Symbol* name) {411assert (index == index_for(name, NULL), "incorrect index?");412413DictionaryEntry* entry = get_entry(index, hash, name, NULL);414return (entry != NULL) ? entry->klass() : (Klass*)NULL;415}416417418void Dictionary::add_protection_domain(int index, unsigned int hash,419instanceKlassHandle klass,420ClassLoaderData* loader_data, Handle protection_domain,421TRAPS) {422Symbol* klass_name = klass->name();423DictionaryEntry* entry = get_entry(index, hash, klass_name, loader_data);424425assert(entry != NULL,"entry must be present, we just created it");426assert(protection_domain() != NULL,427"real protection domain should be present");428429entry->add_protection_domain(this, protection_domain());430431assert(entry->contains_protection_domain(protection_domain()),432"now protection domain should be present");433}434435436bool Dictionary::is_valid_protection_domain(int index, unsigned int hash,437Symbol* name,438ClassLoaderData* loader_data,439Handle protection_domain) {440DictionaryEntry* entry = get_entry(index, hash, name, loader_data);441return entry->is_valid_protection_domain(protection_domain);442}443444445void Dictionary::reorder_dictionary() {446447// Copy all the dictionary entries into a single master list.448449DictionaryEntry* master_list = NULL;450for (int i = 0; i < table_size(); ++i) {451DictionaryEntry* p = bucket(i);452while (p != NULL) {453DictionaryEntry* tmp;454tmp = p->next();455p->set_next(master_list);456master_list = p;457p = tmp;458}459set_entry(i, NULL);460}461462// Add the dictionary entries back to the list in the correct buckets.463while (master_list != NULL) {464DictionaryEntry* p = master_list;465master_list = master_list->next();466p->set_next(NULL);467Symbol* class_name = InstanceKlass::cast((Klass*)(p->klass()))->name();468// Since the null class loader data isn't copied to the CDS archive,469// compute the hash with NULL for loader data.470unsigned int hash = compute_hash(class_name, NULL);471int index = hash_to_index(hash);472p->set_hash(hash);473p->set_loader_data(NULL); // loader_data isn't copied to CDS474p->set_next(bucket(index));475set_entry(index, p);476}477}478479ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)480: Hashtable<oop, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))481{482}483484void ProtectionDomainCacheTable::unlink(BoolObjectClosure* is_alive) {485assert(SafepointSynchronize::is_at_safepoint(), "must be");486for (int i = 0; i < table_size(); ++i) {487ProtectionDomainCacheEntry** p = bucket_addr(i);488ProtectionDomainCacheEntry* entry = bucket(i);489while (entry != NULL) {490if (is_alive->do_object_b(entry->literal())) {491p = entry->next_addr();492} else {493*p = entry->next();494free_entry(entry);495}496entry = *p;497}498}499}500501void ProtectionDomainCacheTable::oops_do(OopClosure* f) {502for (int index = 0; index < table_size(); index++) {503for (ProtectionDomainCacheEntry* probe = bucket(index);504probe != NULL;505probe = probe->next()) {506probe->oops_do(f);507}508}509}510511void ProtectionDomainCacheTable::roots_oops_do(OopClosure* strong, OopClosure* weak) {512for (int index = 0; index < table_size(); index++) {513for (ProtectionDomainCacheEntry* probe = bucket(index);514probe != NULL;515probe = probe->next()) {516if (probe->is_strongly_reachable()) {517probe->reset_strongly_reachable();518probe->oops_do(strong);519} else {520if (weak != NULL) {521probe->oops_do(weak);522}523}524}525}526}527528uint ProtectionDomainCacheTable::bucket_size() {529return sizeof(ProtectionDomainCacheEntry);530}531532#ifndef PRODUCT533void ProtectionDomainCacheTable::print() {534tty->print_cr("Protection domain cache table (table_size=%d, classes=%d)",535table_size(), number_of_entries());536for (int index = 0; index < table_size(); index++) {537for (ProtectionDomainCacheEntry* probe = bucket(index);538probe != NULL;539probe = probe->next()) {540probe->print();541}542}543}544545void ProtectionDomainCacheEntry::print() {546tty->print_cr("entry " PTR_FORMAT " value " PTR_FORMAT " strongly_reachable %d next " PTR_FORMAT,547this, (void*)literal(), _strongly_reachable, next());548}549#endif550551void ProtectionDomainCacheTable::verify() {552int element_count = 0;553for (int index = 0; index < table_size(); index++) {554for (ProtectionDomainCacheEntry* probe = bucket(index);555probe != NULL;556probe = probe->next()) {557probe->verify();558element_count++;559}560}561guarantee(number_of_entries() == element_count,562"Verify of protection domain cache table failed");563debug_only(verify_lookup_length((double)number_of_entries() / table_size()));564}565566void ProtectionDomainCacheEntry::verify() {567guarantee(literal()->is_oop(), "must be an oop");568}569570void ProtectionDomainCacheTable::always_strong_oops_do(OopClosure* f) {571// the caller marked the protection domain cache entries that we need to apply572// the closure on. Only process them.573for (int index = 0; index < table_size(); index++) {574for (ProtectionDomainCacheEntry* probe = bucket(index);575probe != NULL;576probe = probe->next()) {577if (probe->is_strongly_reachable()) {578probe->reset_strongly_reachable();579probe->oops_do(f);580}581}582}583}584585ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(oop protection_domain) {586unsigned int hash = compute_hash(protection_domain);587int index = hash_to_index(hash);588589ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain);590if (entry == NULL) {591entry = add_entry(index, hash, protection_domain);592}593return entry;594}595596ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, oop protection_domain) {597for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) {598if (e->protection_domain() == protection_domain) {599return e;600}601}602603return NULL;604}605606ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, oop protection_domain) {607assert_locked_or_safepoint(SystemDictionary_lock);608assert(index == index_for(protection_domain), "incorrect index?");609assert(find_entry(index, protection_domain) == NULL, "no double entry");610611ProtectionDomainCacheEntry* p = new_entry(hash, protection_domain);612Hashtable<oop, mtClass>::add_entry(index, p);613return p;614}615616void ProtectionDomainCacheTable::free(ProtectionDomainCacheEntry* to_delete) {617unsigned int hash = compute_hash(to_delete->protection_domain());618int index = hash_to_index(hash);619620ProtectionDomainCacheEntry** p = bucket_addr(index);621ProtectionDomainCacheEntry* entry = bucket(index);622while (true) {623assert(entry != NULL, "sanity");624625if (entry == to_delete) {626*p = entry->next();627Hashtable<oop, mtClass>::free_entry(entry);628break;629} else {630p = entry->next_addr();631entry = *p;632}633}634}635636SymbolPropertyTable::SymbolPropertyTable(int table_size)637: Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))638{639}640SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t,641int number_of_entries)642: Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)643{644}645646647SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,648Symbol* sym,649intptr_t sym_mode) {650assert(index == index_for(sym, sym_mode), "incorrect index?");651for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {652if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) {653return p;654}655}656return NULL;657}658659660SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash,661Symbol* sym, intptr_t sym_mode) {662assert_locked_or_safepoint(SystemDictionary_lock);663assert(index == index_for(sym, sym_mode), "incorrect index?");664assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry");665666SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);667Hashtable<Symbol*, mtSymbol>::add_entry(index, p);668return p;669}670671void SymbolPropertyTable::oops_do(OopClosure* f) {672for (int index = 0; index < table_size(); index++) {673for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {674if (p->method_type() != NULL) {675f->do_oop(p->method_type_addr());676}677}678}679}680681void SymbolPropertyTable::methods_do(void f(Method*)) {682for (int index = 0; index < table_size(); index++) {683for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {684Method* prop = p->method();685if (prop != NULL) {686f((Method*)prop);687}688}689}690}691692693// ----------------------------------------------------------------------------694695void Dictionary::print(bool details) {696ResourceMark rm;697HandleMark hm;698699if (details) {700tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",701table_size(), number_of_entries());702tty->print_cr("^ indicates that initiating loader is different from "703"defining loader");704}705706for (int index = 0; index < table_size(); index++) {707for (DictionaryEntry* probe = bucket(index);708probe != NULL;709probe = probe->next()) {710if (Verbose) tty->print("%4d: ", index);711Klass* e = probe->klass();712ClassLoaderData* loader_data = probe->loader_data();713bool is_defining_class =714(loader_data == InstanceKlass::cast(e)->class_loader_data());715tty->print("%s%s", ((!details) || is_defining_class) ? " " : "^",716e->external_name());717718if (details) {719tty->print(", loader ");720if (loader_data != NULL) {721loader_data->print_value();722} else {723tty->print("NULL");724}725}726tty->cr();727}728}729730if (details) {731tty->cr();732_pd_cache_table->print();733}734tty->cr();735}736737void Dictionary::verify() {738guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");739740int element_count = 0;741for (int index = 0; index < table_size(); index++) {742for (DictionaryEntry* probe = bucket(index);743probe != NULL;744probe = probe->next()) {745Klass* e = probe->klass();746ClassLoaderData* loader_data = probe->loader_data();747guarantee(e->oop_is_instance(),748"Verify of system dictionary failed");749// class loader must be present; a null class loader is the750// boostrap loader751guarantee(loader_data != NULL || DumpSharedSpaces ||752loader_data->class_loader() == NULL ||753loader_data->class_loader()->is_instance(),754"checking type of class_loader");755e->verify();756probe->verify_protection_domain_set();757element_count++;758}759}760guarantee(number_of_entries() == element_count,761"Verify of system dictionary failed");762debug_only(verify_lookup_length((double)number_of_entries() / table_size()));763764_pd_cache_table->verify();765}766767768769