Path: blob/master/src/hotspot/share/classfile/dictionary.hpp
40950 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#ifndef SHARE_CLASSFILE_DICTIONARY_HPP25#define SHARE_CLASSFILE_DICTIONARY_HPP2627#include "oops/instanceKlass.hpp"28#include "oops/oop.hpp"29#include "oops/oopHandle.hpp"30#include "utilities/hashtable.hpp"31#include "utilities/ostream.hpp"3233class DictionaryEntry;34class ProtectionDomainEntry;35template <typename T> class GrowableArray;3637//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~38// The data structure for the class loader data dictionaries.3940class Dictionary : public Hashtable<InstanceKlass*, mtClass> {41friend class VMStructs;4243static bool _some_dictionary_needs_resizing;44bool _resizable;45bool _needs_resizing;46void check_if_needs_resize();4748ClassLoaderData* _loader_data; // backpointer to owning loader49ClassLoaderData* loader_data() const { return _loader_data; }5051DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name);5253public:54Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable = false);55Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries, bool resizable = false);56~Dictionary();5758static bool does_any_dictionary_needs_resizing();59bool resize_if_needed();6061void add_klass(unsigned int hash, Symbol* class_name, InstanceKlass* obj);6263InstanceKlass* find_class(unsigned int hash, Symbol* name);6465void classes_do(void f(InstanceKlass*));66void classes_do(void f(InstanceKlass*, TRAPS), TRAPS);67void all_entries_do(KlassClosure* closure);68void classes_do(MetaspaceClosure* it);6970void clean_cached_protection_domains(GrowableArray<ProtectionDomainEntry*>* delete_list);7172// Protection domains73InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);74void validate_protection_domain(unsigned int name_hash,75InstanceKlass* klass,76Handle class_loader,77Handle protection_domain,78TRAPS);7980void print_on(outputStream* st) const;81void verify();8283private:84DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass);8586DictionaryEntry* bucket(int i) const {87return (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::bucket(i);88}8990// The following method is not MT-safe and must be done under lock.91DictionaryEntry** bucket_addr(int i) {92return (DictionaryEntry**)Hashtable<InstanceKlass*, mtClass>::bucket_addr(i);93}9495void free_entry(DictionaryEntry* entry);9697bool is_valid_protection_domain(unsigned int hash,98Symbol* name,99Handle protection_domain);100void add_protection_domain(int index, unsigned int hash,101InstanceKlass* klass,102Handle protection_domain);103};104105// An entry in the class loader data dictionaries, this describes a class as106// { InstanceKlass*, protection_domain }.107108class DictionaryEntry : public HashtableEntry<InstanceKlass*, mtClass> {109friend class VMStructs;110private:111// Contains the set of approved protection domains that can access112// this dictionary entry.113//114// [Note that C.protection_domain(), which is stored in the java.lang.Class115// mirror of C, is NOT the same as PD]116//117// If an entry for PD exists in the list, it means that118// it is okay for a caller class to reference the class in this dictionary entry.119//120// The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()121// It is essentially a cache to avoid repeated Java up-calls to122// ClassLoader.checkPackageAccess().123//124ProtectionDomainEntry* volatile _pd_set;125126public:127// Tells whether a protection is in the approved set.128bool contains_protection_domain(oop protection_domain) const;129// Adds a protection domain to the approved set.130void add_protection_domain(ClassLoaderData* loader_data, Handle protection_domain);131132InstanceKlass* instance_klass() const { return literal(); }133InstanceKlass** klass_addr() { return (InstanceKlass**)literal_addr(); }134135DictionaryEntry* next() const {136return (DictionaryEntry*)HashtableEntry<InstanceKlass*, mtClass>::next();137}138139DictionaryEntry** next_addr() {140return (DictionaryEntry**)HashtableEntry<InstanceKlass*, mtClass>::next_addr();141}142143ProtectionDomainEntry* pd_set_acquire() const { return Atomic::load_acquire(&_pd_set); }144void release_set_pd_set(ProtectionDomainEntry* entry) { Atomic::release_store(&_pd_set, entry); }145146// Tells whether the initiating class' protection domain can access the klass in this entry147inline bool is_valid_protection_domain(Handle protection_domain);148void verify_protection_domain_set();149150void print_count(outputStream *st);151void verify();152};153154// Entry in a SymbolPropertyTable, mapping a single Symbol*155// to a managed and an unmanaged pointer.156class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {157friend class VMStructs;158private:159intptr_t _symbol_mode; // secondary key160Method* _method;161OopHandle _method_type;162163public:164Symbol* symbol() const { return literal(); }165166intptr_t symbol_mode() const { return _symbol_mode; }167void set_symbol_mode(intptr_t m) { _symbol_mode = m; }168169Method* method() const { return _method; }170void set_method(Method* p) { _method = p; }171172oop method_type() const;173void set_method_type(oop p);174175// We need to clear the OopHandle because these hashtable entries are not constructed properly.176void clear_method_type() { _method_type = OopHandle(); }177178void free_entry();179180SymbolPropertyEntry* next() const {181return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next();182}183184SymbolPropertyEntry** next_addr() {185return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr();186}187188void print_entry(outputStream* st) const;189};190191// A system-internal mapping of symbols to pointers, both managed192// and unmanaged. Used to record the auto-generation of each method193// MethodHandle.invoke(S)T, for all signatures (S)T.194class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {195friend class VMStructs;196private:197// The following method is not MT-safe and must be done under lock.198SymbolPropertyEntry** bucket_addr(int i) {199return (SymbolPropertyEntry**) Hashtable<Symbol*, mtSymbol>::bucket_addr(i);200}201202void add_entry(int index, SymbolPropertyEntry* new_entry) {203ShouldNotReachHere();204}205void set_entry(int index, SymbolPropertyEntry* new_entry) {206ShouldNotReachHere();207}208209SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {210SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol);211// Hashtable with Symbol* literal must increment and decrement refcount.212symbol->increment_refcount();213entry->set_symbol_mode(symbol_mode);214entry->set_method(NULL);215entry->clear_method_type();216return entry;217}218219public:220SymbolPropertyTable(int table_size);221SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, int number_of_entries);222223void free_entry(SymbolPropertyEntry* entry);224225unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {226// Use the regular identity_hash.227return Hashtable<Symbol*, mtSymbol>::compute_hash(sym) ^ symbol_mode;228}229230int index_for(Symbol* name, intptr_t symbol_mode) {231return hash_to_index(compute_hash(name, symbol_mode));232}233234// need not be locked; no state change235SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);236237// must be done under SystemDictionary_lock238SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);239240void methods_do(void f(Method*));241242void verify();243244SymbolPropertyEntry* bucket(int i) {245return (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::bucket(i);246}247};248#endif // SHARE_CLASSFILE_DICTIONARY_HPP249250251