dictionary.hpp revision 1472:c18cbe5936b8
1/* 2 * Copyright (c) 2003, 2009, 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 */ 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 221// Entry in a SymbolPropertyTable, mapping a single symbolOop 222// to a managed and an unmanaged pointer. 223class SymbolPropertyEntry : public HashtableEntry { 224 friend class VMStructs; 225 private: 226 intptr_t _symbol_mode; // secondary key 227 oop _property_oop; 228 address _property_data; 229 230 public: 231 symbolOop symbol() const { return (symbolOop) literal(); } 232 233 intptr_t symbol_mode() const { return _symbol_mode; } 234 void set_symbol_mode(intptr_t m) { _symbol_mode = m; } 235 236 oop property_oop() const { return _property_oop; } 237 void set_property_oop(oop p) { _property_oop = p; } 238 239 address property_data() const { return _property_data; } 240 void set_property_data(address p) { _property_data = p; } 241 242 SymbolPropertyEntry* next() const { 243 return (SymbolPropertyEntry*)HashtableEntry::next(); 244 } 245 246 SymbolPropertyEntry** next_addr() { 247 return (SymbolPropertyEntry**)HashtableEntry::next_addr(); 248 } 249 250 oop* symbol_addr() { return literal_addr(); } 251 oop* property_oop_addr() { return &_property_oop; } 252 253 void print_on(outputStream* st) const { 254 symbol()->print_value_on(st); 255 st->print("/mode="INTX_FORMAT, symbol_mode()); 256 st->print(" -> "); 257 bool printed = false; 258 if (property_oop() != NULL) { 259 property_oop()->print_value_on(st); 260 printed = true; 261 } 262 if (property_data() != NULL) { 263 if (printed) st->print(" and "); 264 st->print(INTPTR_FORMAT, property_data()); 265 printed = true; 266 } 267 st->print_cr(printed ? "" : "(empty)"); 268 } 269}; 270 271// A system-internal mapping of symbols to pointers, both managed 272// and unmanaged. Used to record the auto-generation of each method 273// MethodHandle.invoke(S)T, for all signatures (S)T. 274class SymbolPropertyTable : public Hashtable { 275 friend class VMStructs; 276private: 277 SymbolPropertyEntry* bucket(int i) { 278 return (SymbolPropertyEntry*) Hashtable::bucket(i); 279 } 280 281 // The following method is not MT-safe and must be done under lock. 282 SymbolPropertyEntry** bucket_addr(int i) { 283 return (SymbolPropertyEntry**) Hashtable::bucket_addr(i); 284 } 285 286 void add_entry(int index, SymbolPropertyEntry* new_entry) { 287 ShouldNotReachHere(); 288 } 289 void set_entry(int index, SymbolPropertyEntry* new_entry) { 290 ShouldNotReachHere(); 291 } 292 293 SymbolPropertyEntry* new_entry(unsigned int hash, symbolOop symbol, intptr_t symbol_mode) { 294 SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol); 295 entry->set_symbol_mode(symbol_mode); 296 entry->set_property_oop(NULL); 297 entry->set_property_data(NULL); 298 return entry; 299 } 300 301public: 302 SymbolPropertyTable(int table_size); 303 SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries); 304 305 void free_entry(SymbolPropertyEntry* entry) { 306 Hashtable::free_entry(entry); 307 } 308 309 unsigned int compute_hash(symbolHandle sym, intptr_t symbol_mode) { 310 // Use the regular identity_hash. 311 return Hashtable::compute_hash(sym) ^ symbol_mode; 312 } 313 314 int index_for(symbolHandle name, intptr_t symbol_mode) { 315 return hash_to_index(compute_hash(name, symbol_mode)); 316 } 317 318 // need not be locked; no state change 319 SymbolPropertyEntry* find_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode); 320 321 // must be done under SystemDictionary_lock 322 SymbolPropertyEntry* add_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode); 323 324 // GC support 325 void oops_do(OopClosure* f); 326 void methods_do(void f(methodOop)); 327 328 // Sharing support 329 void dump(SerializeOopClosure* soc); 330 void restore(SerializeOopClosure* soc); 331 void reorder_dictionary(); 332 333#ifndef PRODUCT 334 void print(); 335#endif 336 void verify(); 337}; 338 339