src/share/vm/classfile/dictionary.hpp

Tue, 22 Mar 2011 13:36:33 -0700

author
jcoomes
date
Tue, 22 Mar 2011 13:36:33 -0700
changeset 2661
b099aaf51bf8
parent 2497
3582bf76420e
child 2708
1d1603768966
permissions
-rw-r--r--

6962931: move interned strings out of the perm gen
Reviewed-by: never, coleenp, ysr, jwilhelm

     1 /*
     2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_CLASSFILE_DICTIONARY_HPP
    26 #define SHARE_VM_CLASSFILE_DICTIONARY_HPP
    28 #include "classfile/systemDictionary.hpp"
    29 #include "oops/instanceKlass.hpp"
    30 #include "oops/oop.hpp"
    31 #include "utilities/hashtable.hpp"
    33 class DictionaryEntry;
    35 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    36 // The data structure for the system dictionary (and the shared system
    37 // dictionary).
    39 class Dictionary : public TwoOopHashtable<klassOop> {
    40   friend class VMStructs;
    41 private:
    42   // current iteration index.
    43   static int                    _current_class_index;
    44   // pointer to the current hash table entry.
    45   static DictionaryEntry*       _current_class_entry;
    47   DictionaryEntry* get_entry(int index, unsigned int hash,
    48                              Symbol* name, Handle loader);
    50   DictionaryEntry* bucket(int i) {
    51     return (DictionaryEntry*)Hashtable<klassOop>::bucket(i);
    52   }
    54   // The following method is not MT-safe and must be done under lock.
    55   DictionaryEntry** bucket_addr(int i) {
    56     return (DictionaryEntry**)Hashtable<klassOop>::bucket_addr(i);
    57   }
    59   void add_entry(int index, DictionaryEntry* new_entry) {
    60     Hashtable<klassOop>::add_entry(index, (HashtableEntry<oop>*)new_entry);
    61   }
    64 public:
    65   Dictionary(int table_size);
    66   Dictionary(int table_size, HashtableBucket* t, int number_of_entries);
    68   DictionaryEntry* new_entry(unsigned int hash, klassOop klass, oop loader);
    70   DictionaryEntry* new_entry();
    72   void free_entry(DictionaryEntry* entry);
    74   void add_klass(Symbol* class_name, Handle class_loader,KlassHandle obj);
    76   klassOop find_class(int index, unsigned int hash,
    77                       Symbol* name, Handle loader);
    79   klassOop find_shared_class(int index, unsigned int hash, Symbol* name);
    81   // Compiler support
    82   klassOop try_get_next_class();
    84   // GC support
    86   void oops_do(OopClosure* f);
    87   void always_strong_classes_do(OopClosure* blk);
    88   void classes_do(void f(klassOop));
    89   void classes_do(void f(klassOop, TRAPS), TRAPS);
    90   void classes_do(void f(klassOop, oop));
    91   void classes_do(void f(klassOop, oop, TRAPS), TRAPS);
    93   void methods_do(void f(methodOop));
    96   // Classes loaded by the bootstrap loader are always strongly reachable.
    97   // If we're not doing class unloading, all classes are strongly reachable.
    98   static bool is_strongly_reachable(oop class_loader, klassOop klass) {
    99     assert (klass != NULL, "should have non-null klass");
   100     return (class_loader == NULL || !ClassUnloading);
   101   }
   103   // Unload (that is, break root links to) all unmarked classes and
   104   // loaders.  Returns "true" iff something was unloaded.
   105   bool do_unloading(BoolObjectClosure* is_alive);
   107   // Protection domains
   108   klassOop find(int index, unsigned int hash, Symbol* name,
   109                 Handle loader, Handle protection_domain, TRAPS);
   110   bool is_valid_protection_domain(int index, unsigned int hash,
   111                                   Symbol* name, Handle class_loader,
   112                                   Handle protection_domain);
   113   void add_protection_domain(int index, unsigned int hash,
   114                              instanceKlassHandle klass, Handle loader,
   115                              Handle protection_domain, TRAPS);
   117   // Sharing support
   118   void dump(SerializeOopClosure* soc);
   119   void restore(SerializeOopClosure* soc);
   120   void reorder_dictionary();
   123 #ifndef PRODUCT
   124   void print();
   125 #endif
   126   void verify();
   127 };
   129 // The following classes can be in dictionary.cpp, but we need these
   130 // to be in header file so that SA's vmStructs can access.
   132 class ProtectionDomainEntry :public CHeapObj {
   133   friend class VMStructs;
   134  public:
   135   ProtectionDomainEntry* _next;
   136   oop                    _protection_domain;
   138   ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) {
   139     _protection_domain = protection_domain;
   140     _next              = next;
   141   }
   143   ProtectionDomainEntry* next() { return _next; }
   144   oop protection_domain() { return _protection_domain; }
   145 };
   147 // An entry in the system dictionary, this describes a class as
   148 // { klassOop, loader, protection_domain }.
   150 class DictionaryEntry : public HashtableEntry<klassOop> {
   151   friend class VMStructs;
   152  private:
   153   // Contains the set of approved protection domains that can access
   154   // this system dictionary entry.
   155   ProtectionDomainEntry* _pd_set;
   156   oop                    _loader;
   159  public:
   160   // Tells whether a protection is in the approved set.
   161   bool contains_protection_domain(oop protection_domain) const;
   162   // Adds a protection domain to the approved set.
   163   void add_protection_domain(oop protection_domain);
   165   klassOop klass() const { return (klassOop)literal(); }
   166   klassOop* klass_addr() { return (klassOop*)literal_addr(); }
   168   DictionaryEntry* next() const {
   169     return (DictionaryEntry*)HashtableEntry<klassOop>::next();
   170   }
   172   DictionaryEntry** next_addr() {
   173     return (DictionaryEntry**)HashtableEntry<klassOop>::next_addr();
   174   }
   176   oop loader() const { return _loader; }
   177   void set_loader(oop loader) { _loader = loader; }
   178   oop* loader_addr() { return &_loader; }
   180   ProtectionDomainEntry* pd_set() const { return _pd_set; }
   181   void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }
   183   bool has_protection_domain() { return _pd_set != NULL; }
   185   // Tells whether the initiating class' protection can access the this _klass
   186   bool is_valid_protection_domain(Handle protection_domain) {
   187     if (!ProtectionDomainVerification) return true;
   188     if (!SystemDictionary::has_checkPackageAccess()) return true;
   190     return protection_domain() == NULL
   191          ? true
   192          : contains_protection_domain(protection_domain());
   193   }
   196   void protection_domain_set_oops_do(OopClosure* f) {
   197     for (ProtectionDomainEntry* current = _pd_set;
   198                                 current != NULL;
   199                                 current = current->_next) {
   200       f->do_oop(&(current->_protection_domain));
   201     }
   202   }
   204   void verify_protection_domain_set() {
   205     for (ProtectionDomainEntry* current = _pd_set;
   206                                 current != NULL;
   207                                 current = current->_next) {
   208       current->_protection_domain->verify();
   209     }
   210   }
   212   bool equals(Symbol* class_name, oop class_loader) const {
   213     klassOop klass = (klassOop)literal();
   214     return (instanceKlass::cast(klass)->name() == class_name &&
   215             _loader == class_loader);
   216   }
   218   void print() {
   219     int count = 0;
   220     for (ProtectionDomainEntry* current = _pd_set;
   221                                 current != NULL;
   222                                 current = current->_next) {
   223       count++;
   224     }
   225     tty->print_cr("pd set = #%d", count);
   226   }
   227 };
   229 // Entry in a SymbolPropertyTable, mapping a single Symbol*
   230 // to a managed and an unmanaged pointer.
   231 class SymbolPropertyEntry : public HashtableEntry<Symbol*> {
   232   friend class VMStructs;
   233  private:
   234   intptr_t _symbol_mode;  // secondary key
   235   oop     _property_oop;
   236   address _property_data;
   238  public:
   239   Symbol* symbol() const            { return literal(); }
   241   intptr_t symbol_mode() const      { return _symbol_mode; }
   242   void set_symbol_mode(intptr_t m)  { _symbol_mode = m; }
   244   oop      property_oop() const     { return _property_oop; }
   245   void set_property_oop(oop p)      { _property_oop = p; }
   247   address  property_data() const    { return _property_data; }
   248   void set_property_data(address p) { _property_data = p; }
   250   SymbolPropertyEntry* next() const {
   251     return (SymbolPropertyEntry*)HashtableEntry<Symbol*>::next();
   252   }
   254   SymbolPropertyEntry** next_addr() {
   255     return (SymbolPropertyEntry**)HashtableEntry<Symbol*>::next_addr();
   256   }
   258   oop* property_oop_addr()          { return &_property_oop; }
   260   void print_on(outputStream* st) const {
   261     symbol()->print_value_on(st);
   262     st->print("/mode="INTX_FORMAT, symbol_mode());
   263     st->print(" -> ");
   264     bool printed = false;
   265     if (property_oop() != NULL) {
   266       property_oop()->print_value_on(st);
   267       printed = true;
   268     }
   269     if (property_data() != NULL) {
   270       if (printed)  st->print(" and ");
   271       st->print(INTPTR_FORMAT, property_data());
   272       printed = true;
   273     }
   274     st->print_cr(printed ? "" : "(empty)");
   275   }
   276 };
   278 // A system-internal mapping of symbols to pointers, both managed
   279 // and unmanaged.  Used to record the auto-generation of each method
   280 // MethodHandle.invoke(S)T, for all signatures (S)T.
   281 class SymbolPropertyTable : public Hashtable<Symbol*> {
   282   friend class VMStructs;
   283 private:
   284   SymbolPropertyEntry* bucket(int i) {
   285     return (SymbolPropertyEntry*) Hashtable<Symbol*>::bucket(i);
   286   }
   288   // The following method is not MT-safe and must be done under lock.
   289   SymbolPropertyEntry** bucket_addr(int i) {
   290     return (SymbolPropertyEntry**) Hashtable<Symbol*>::bucket_addr(i);
   291   }
   293   void add_entry(int index, SymbolPropertyEntry* new_entry) {
   294     ShouldNotReachHere();
   295   }
   296   void set_entry(int index, SymbolPropertyEntry* new_entry) {
   297     ShouldNotReachHere();
   298   }
   300   SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
   301     SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*>::new_entry(hash, symbol);
   302     // Hashtable with Symbol* literal must increment and decrement refcount.
   303     symbol->increment_refcount();
   304     entry->set_symbol_mode(symbol_mode);
   305     entry->set_property_oop(NULL);
   306     entry->set_property_data(NULL);
   307     return entry;
   308   }
   310 public:
   311   SymbolPropertyTable(int table_size);
   312   SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
   314   void free_entry(SymbolPropertyEntry* entry) {
   315     // decrement Symbol refcount here because hashtable doesn't.
   316     entry->literal()->decrement_refcount();
   317     Hashtable<Symbol*>::free_entry(entry);
   318   }
   320   unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
   321     // Use the regular identity_hash.
   322     return Hashtable<Symbol*>::compute_hash(sym) ^ symbol_mode;
   323   }
   325   int index_for(Symbol* name, intptr_t symbol_mode) {
   326     return hash_to_index(compute_hash(name, symbol_mode));
   327   }
   329   // need not be locked; no state change
   330   SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
   332   // must be done under SystemDictionary_lock
   333   SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
   335   // GC support
   336   void oops_do(OopClosure* f);
   337   void methods_do(void f(methodOop));
   339   // Sharing support
   340   void dump(SerializeOopClosure* soc);
   341   void restore(SerializeOopClosure* soc);
   342   void reorder_dictionary();
   344 #ifndef PRODUCT
   345   void print();
   346 #endif
   347   void verify();
   348 };
   349 #endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP

mercurial