src/share/vm/classfile/dictionary.hpp

Fri, 12 Nov 2010 09:37:13 -0500

author
zgu
date
Fri, 12 Nov 2010 09:37:13 -0500
changeset 2299
9752a6549f2e
parent 1907
c18cbe5936b8
child 2314
f95d63e2154a
permissions
-rw-r--r--

Merge

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

mercurial