dictionary.hpp revision 0:a61af66fc99e
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 25class DictionaryEntry; 26 27//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28// The data structure for the system dictionary (and the shared system 29// dictionary). 30 31class Dictionary : public TwoOopHashtable { 32 friend class VMStructs; 33private: 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 56public: 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 124class 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 142class 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}; 220