src/share/vm/classfile/dictionary.hpp

Wed, 11 Jan 2012 17:34:02 -0500

author
phh
date
Wed, 11 Jan 2012 17:34:02 -0500
changeset 3427
94ec88ca68e2
parent 2708
1d1603768966
child 3900
d2a62e0f25eb
permissions
-rw-r--r--

7115199: Add event tracing hooks and Java Flight Recorder infrastructure
Summary: Added a nop tracing infrastructure, JFR makefile changes and other infrastructure used only by JFR.
Reviewed-by: acorn, sspitsyn
Contributed-by: markus.gronlund@oracle.com

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

mercurial