hotspot/src/share/vm/classfile/dictionary.hpp
changeset 1 489c9b5090e2
child 2534 08dac9ce0cd7
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 2003-2006 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 class DictionaryEntry;
       
    26 
       
    27 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
    28 // The data structure for the system dictionary (and the shared system
       
    29 // dictionary).
       
    30 
       
    31 class Dictionary : public TwoOopHashtable {
       
    32   friend class VMStructs;
       
    33 private:
       
    34   // current iteration index.
       
    35   static int                    _current_class_index;
       
    36   // pointer to the current hash table entry.
       
    37   static DictionaryEntry*       _current_class_entry;
       
    38 
       
    39   DictionaryEntry* get_entry(int index, unsigned int hash,
       
    40                              symbolHandle name, Handle loader);
       
    41 
       
    42   DictionaryEntry* bucket(int i) {
       
    43     return (DictionaryEntry*)Hashtable::bucket(i);
       
    44   }
       
    45 
       
    46   // The following method is not MT-safe and must be done under lock.
       
    47   DictionaryEntry** bucket_addr(int i) {
       
    48     return (DictionaryEntry**)Hashtable::bucket_addr(i);
       
    49   }
       
    50 
       
    51   void add_entry(int index, DictionaryEntry* new_entry) {
       
    52     Hashtable::add_entry(index, (HashtableEntry*)new_entry);
       
    53   }
       
    54 
       
    55 
       
    56 public:
       
    57   Dictionary(int table_size);
       
    58   Dictionary(int table_size, HashtableBucket* t, int number_of_entries);
       
    59 
       
    60   DictionaryEntry* new_entry(unsigned int hash, klassOop klass, oop loader);
       
    61 
       
    62   DictionaryEntry* new_entry();
       
    63 
       
    64   void free_entry(DictionaryEntry* entry);
       
    65 
       
    66   void add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj);
       
    67 
       
    68   klassOop find_class(int index, unsigned int hash,
       
    69                       symbolHandle name, Handle loader);
       
    70 
       
    71   klassOop find_shared_class(int index, unsigned int hash, symbolHandle name);
       
    72 
       
    73   // Compiler support
       
    74   klassOop try_get_next_class();
       
    75 
       
    76   // GC support
       
    77 
       
    78   void oops_do(OopClosure* f);
       
    79   void always_strong_classes_do(OopClosure* blk);
       
    80   void classes_do(void f(klassOop));
       
    81   void classes_do(void f(klassOop, TRAPS), TRAPS);
       
    82   void classes_do(void f(klassOop, oop));
       
    83   void classes_do(void f(klassOop, oop, TRAPS), TRAPS);
       
    84 
       
    85   void methods_do(void f(methodOop));
       
    86 
       
    87 
       
    88   // Classes loaded by the bootstrap loader are always strongly reachable.
       
    89   // If we're not doing class unloading, all classes are strongly reachable.
       
    90   static bool is_strongly_reachable(oop class_loader, oop klass) {
       
    91     assert (klass != NULL, "should have non-null klass");
       
    92     return (class_loader == NULL || !ClassUnloading);
       
    93   }
       
    94 
       
    95   // Unload (that is, break root links to) all unmarked classes and
       
    96   // loaders.  Returns "true" iff something was unloaded.
       
    97   bool do_unloading(BoolObjectClosure* is_alive);
       
    98 
       
    99   // Protection domains
       
   100   klassOop find(int index, unsigned int hash, symbolHandle name,
       
   101                 Handle loader, Handle protection_domain, TRAPS);
       
   102   bool is_valid_protection_domain(int index, unsigned int hash,
       
   103                                   symbolHandle name, Handle class_loader,
       
   104                                   Handle protection_domain);
       
   105   void add_protection_domain(int index, unsigned int hash,
       
   106                              instanceKlassHandle klass, Handle loader,
       
   107                              Handle protection_domain, TRAPS);
       
   108 
       
   109   // Sharing support
       
   110   void dump(SerializeOopClosure* soc);
       
   111   void restore(SerializeOopClosure* soc);
       
   112   void reorder_dictionary();
       
   113 
       
   114 
       
   115 #ifndef PRODUCT
       
   116   void print();
       
   117 #endif
       
   118   void verify();
       
   119 };
       
   120 
       
   121 // The following classes can be in dictionary.cpp, but we need these
       
   122 // to be in header file so that SA's vmStructs can access.
       
   123 
       
   124 class ProtectionDomainEntry :public CHeapObj {
       
   125   friend class VMStructs;
       
   126  public:
       
   127   ProtectionDomainEntry* _next;
       
   128   oop                    _protection_domain;
       
   129 
       
   130   ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) {
       
   131     _protection_domain = protection_domain;
       
   132     _next              = next;
       
   133   }
       
   134 
       
   135   ProtectionDomainEntry* next() { return _next; }
       
   136   oop protection_domain() { return _protection_domain; }
       
   137 };
       
   138 
       
   139 // An entry in the system dictionary, this describes a class as
       
   140 // { klassOop, loader, protection_domain }.
       
   141 
       
   142 class DictionaryEntry : public HashtableEntry {
       
   143   friend class VMStructs;
       
   144  private:
       
   145   // Contains the set of approved protection domains that can access
       
   146   // this system dictionary entry.
       
   147   ProtectionDomainEntry* _pd_set;
       
   148   oop                    _loader;
       
   149 
       
   150 
       
   151  public:
       
   152   // Tells whether a protection is in the approved set.
       
   153   bool contains_protection_domain(oop protection_domain) const;
       
   154   // Adds a protection domain to the approved set.
       
   155   void add_protection_domain(oop protection_domain);
       
   156 
       
   157   klassOop klass() const { return (klassOop)literal(); }
       
   158   klassOop* klass_addr() { return (klassOop*)literal_addr(); }
       
   159 
       
   160   DictionaryEntry* next() const {
       
   161     return (DictionaryEntry*)HashtableEntry::next();
       
   162   }
       
   163 
       
   164   DictionaryEntry** next_addr() {
       
   165     return (DictionaryEntry**)HashtableEntry::next_addr();
       
   166   }
       
   167 
       
   168   oop loader() const { return _loader; }
       
   169   void set_loader(oop loader) { _loader = loader; }
       
   170   oop* loader_addr() { return &_loader; }
       
   171 
       
   172   ProtectionDomainEntry* pd_set() const { return _pd_set; }
       
   173   void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }
       
   174 
       
   175   bool has_protection_domain() { return _pd_set != NULL; }
       
   176 
       
   177   // Tells whether the initiating class' protection can access the this _klass
       
   178   bool is_valid_protection_domain(Handle protection_domain) {
       
   179     if (!ProtectionDomainVerification) return true;
       
   180     if (!SystemDictionary::has_checkPackageAccess()) return true;
       
   181 
       
   182     return protection_domain() == NULL
       
   183          ? true
       
   184          : contains_protection_domain(protection_domain());
       
   185   }
       
   186 
       
   187 
       
   188   void protection_domain_set_oops_do(OopClosure* f) {
       
   189     for (ProtectionDomainEntry* current = _pd_set;
       
   190                                 current != NULL;
       
   191                                 current = current->_next) {
       
   192       f->do_oop(&(current->_protection_domain));
       
   193     }
       
   194   }
       
   195 
       
   196   void verify_protection_domain_set() {
       
   197     for (ProtectionDomainEntry* current = _pd_set;
       
   198                                 current != NULL;
       
   199                                 current = current->_next) {
       
   200       current->_protection_domain->verify();
       
   201     }
       
   202   }
       
   203 
       
   204   bool equals(symbolOop class_name, oop class_loader) const {
       
   205     klassOop klass = (klassOop)literal();
       
   206     return (instanceKlass::cast(klass)->name() == class_name &&
       
   207             _loader == class_loader);
       
   208   }
       
   209 
       
   210   void print() {
       
   211     int count = 0;
       
   212     for (ProtectionDomainEntry* current = _pd_set;
       
   213                                 current != NULL;
       
   214                                 current = current->_next) {
       
   215       count++;
       
   216     }
       
   217     tty->print_cr("pd set = #%d", count);
       
   218   }
       
   219 };