comparison src/share/vm/classfile/dictionary.hpp @ 2177:3582bf76420e

6990754: Use native memory and reference counting to implement SymbolTable Summary: move symbols from permgen into C heap and reference count them Reviewed-by: never, acorn, jmasa, stefank
author coleenp
date Thu, 27 Jan 2011 16:11:27 -0800
parents f95d63e2154a
children 1d1603768966
comparison
equal deleted inserted replaced
2176:27e4ea99855d 2177:3582bf76420e
34 34
35 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 35 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36 // The data structure for the system dictionary (and the shared system 36 // The data structure for the system dictionary (and the shared system
37 // dictionary). 37 // dictionary).
38 38
39 class Dictionary : public TwoOopHashtable { 39 class Dictionary : public TwoOopHashtable<klassOop> {
40 friend class VMStructs; 40 friend class VMStructs;
41 private: 41 private:
42 // current iteration index. 42 // current iteration index.
43 static int _current_class_index; 43 static int _current_class_index;
44 // pointer to the current hash table entry. 44 // pointer to the current hash table entry.
45 static DictionaryEntry* _current_class_entry; 45 static DictionaryEntry* _current_class_entry;
46 46
47 DictionaryEntry* get_entry(int index, unsigned int hash, 47 DictionaryEntry* get_entry(int index, unsigned int hash,
48 symbolHandle name, Handle loader); 48 Symbol* name, Handle loader);
49 49
50 DictionaryEntry* bucket(int i) { 50 DictionaryEntry* bucket(int i) {
51 return (DictionaryEntry*)Hashtable::bucket(i); 51 return (DictionaryEntry*)Hashtable<klassOop>::bucket(i);
52 } 52 }
53 53
54 // The following method is not MT-safe and must be done under lock. 54 // The following method is not MT-safe and must be done under lock.
55 DictionaryEntry** bucket_addr(int i) { 55 DictionaryEntry** bucket_addr(int i) {
56 return (DictionaryEntry**)Hashtable::bucket_addr(i); 56 return (DictionaryEntry**)Hashtable<klassOop>::bucket_addr(i);
57 } 57 }
58 58
59 void add_entry(int index, DictionaryEntry* new_entry) { 59 void add_entry(int index, DictionaryEntry* new_entry) {
60 Hashtable::add_entry(index, (HashtableEntry*)new_entry); 60 Hashtable<klassOop>::add_entry(index, (HashtableEntry<oop>*)new_entry);
61 } 61 }
62 62
63 63
64 public: 64 public:
65 Dictionary(int table_size); 65 Dictionary(int table_size);
69 69
70 DictionaryEntry* new_entry(); 70 DictionaryEntry* new_entry();
71 71
72 void free_entry(DictionaryEntry* entry); 72 void free_entry(DictionaryEntry* entry);
73 73
74 void add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj); 74 void add_klass(Symbol* class_name, Handle class_loader,KlassHandle obj);
75 75
76 klassOop find_class(int index, unsigned int hash, 76 klassOop find_class(int index, unsigned int hash,
77 symbolHandle name, Handle loader); 77 Symbol* name, Handle loader);
78 78
79 klassOop find_shared_class(int index, unsigned int hash, symbolHandle name); 79 klassOop find_shared_class(int index, unsigned int hash, Symbol* name);
80 80
81 // Compiler support 81 // Compiler support
82 klassOop try_get_next_class(); 82 klassOop try_get_next_class();
83 83
84 // GC support 84 // GC support
93 void methods_do(void f(methodOop)); 93 void methods_do(void f(methodOop));
94 94
95 95
96 // Classes loaded by the bootstrap loader are always strongly reachable. 96 // Classes loaded by the bootstrap loader are always strongly reachable.
97 // If we're not doing class unloading, all classes are strongly reachable. 97 // If we're not doing class unloading, all classes are strongly reachable.
98 static bool is_strongly_reachable(oop class_loader, oop klass) { 98 static bool is_strongly_reachable(oop class_loader, klassOop klass) {
99 assert (klass != NULL, "should have non-null klass"); 99 assert (klass != NULL, "should have non-null klass");
100 return (class_loader == NULL || !ClassUnloading); 100 return (class_loader == NULL || !ClassUnloading);
101 } 101 }
102 102
103 // Unload (that is, break root links to) all unmarked classes and 103 // Unload (that is, break root links to) all unmarked classes and
104 // loaders. Returns "true" iff something was unloaded. 104 // loaders. Returns "true" iff something was unloaded.
105 bool do_unloading(BoolObjectClosure* is_alive); 105 bool do_unloading(BoolObjectClosure* is_alive);
106 106
107 // Protection domains 107 // Protection domains
108 klassOop find(int index, unsigned int hash, symbolHandle name, 108 klassOop find(int index, unsigned int hash, Symbol* name,
109 Handle loader, Handle protection_domain, TRAPS); 109 Handle loader, Handle protection_domain, TRAPS);
110 bool is_valid_protection_domain(int index, unsigned int hash, 110 bool is_valid_protection_domain(int index, unsigned int hash,
111 symbolHandle name, Handle class_loader, 111 Symbol* name, Handle class_loader,
112 Handle protection_domain); 112 Handle protection_domain);
113 void add_protection_domain(int index, unsigned int hash, 113 void add_protection_domain(int index, unsigned int hash,
114 instanceKlassHandle klass, Handle loader, 114 instanceKlassHandle klass, Handle loader,
115 Handle protection_domain, TRAPS); 115 Handle protection_domain, TRAPS);
116 116
145 }; 145 };
146 146
147 // An entry in the system dictionary, this describes a class as 147 // An entry in the system dictionary, this describes a class as
148 // { klassOop, loader, protection_domain }. 148 // { klassOop, loader, protection_domain }.
149 149
150 class DictionaryEntry : public HashtableEntry { 150 class DictionaryEntry : public HashtableEntry<klassOop> {
151 friend class VMStructs; 151 friend class VMStructs;
152 private: 152 private:
153 // Contains the set of approved protection domains that can access 153 // Contains the set of approved protection domains that can access
154 // this system dictionary entry. 154 // this system dictionary entry.
155 ProtectionDomainEntry* _pd_set; 155 ProtectionDomainEntry* _pd_set;
164 164
165 klassOop klass() const { return (klassOop)literal(); } 165 klassOop klass() const { return (klassOop)literal(); }
166 klassOop* klass_addr() { return (klassOop*)literal_addr(); } 166 klassOop* klass_addr() { return (klassOop*)literal_addr(); }
167 167
168 DictionaryEntry* next() const { 168 DictionaryEntry* next() const {
169 return (DictionaryEntry*)HashtableEntry::next(); 169 return (DictionaryEntry*)HashtableEntry<klassOop>::next();
170 } 170 }
171 171
172 DictionaryEntry** next_addr() { 172 DictionaryEntry** next_addr() {
173 return (DictionaryEntry**)HashtableEntry::next_addr(); 173 return (DictionaryEntry**)HashtableEntry<klassOop>::next_addr();
174 } 174 }
175 175
176 oop loader() const { return _loader; } 176 oop loader() const { return _loader; }
177 void set_loader(oop loader) { _loader = loader; } 177 void set_loader(oop loader) { _loader = loader; }
178 oop* loader_addr() { return &_loader; } 178 oop* loader_addr() { return &_loader; }
207 current = current->_next) { 207 current = current->_next) {
208 current->_protection_domain->verify(); 208 current->_protection_domain->verify();
209 } 209 }
210 } 210 }
211 211
212 bool equals(symbolOop class_name, oop class_loader) const { 212 bool equals(Symbol* class_name, oop class_loader) const {
213 klassOop klass = (klassOop)literal(); 213 klassOop klass = (klassOop)literal();
214 return (instanceKlass::cast(klass)->name() == class_name && 214 return (instanceKlass::cast(klass)->name() == class_name &&
215 _loader == class_loader); 215 _loader == class_loader);
216 } 216 }
217 217
224 } 224 }
225 tty->print_cr("pd set = #%d", count); 225 tty->print_cr("pd set = #%d", count);
226 } 226 }
227 }; 227 };
228 228
229 // Entry in a SymbolPropertyTable, mapping a single symbolOop 229 // Entry in a SymbolPropertyTable, mapping a single Symbol*
230 // to a managed and an unmanaged pointer. 230 // to a managed and an unmanaged pointer.
231 class SymbolPropertyEntry : public HashtableEntry { 231 class SymbolPropertyEntry : public HashtableEntry<Symbol*> {
232 friend class VMStructs; 232 friend class VMStructs;
233 private: 233 private:
234 intptr_t _symbol_mode; // secondary key 234 intptr_t _symbol_mode; // secondary key
235 oop _property_oop; 235 oop _property_oop;
236 address _property_data; 236 address _property_data;
237 237
238 public: 238 public:
239 symbolOop symbol() const { return (symbolOop) literal(); } 239 Symbol* symbol() const { return literal(); }
240 240
241 intptr_t symbol_mode() const { return _symbol_mode; } 241 intptr_t symbol_mode() const { return _symbol_mode; }
242 void set_symbol_mode(intptr_t m) { _symbol_mode = m; } 242 void set_symbol_mode(intptr_t m) { _symbol_mode = m; }
243 243
244 oop property_oop() const { return _property_oop; } 244 oop property_oop() const { return _property_oop; }
246 246
247 address property_data() const { return _property_data; } 247 address property_data() const { return _property_data; }
248 void set_property_data(address p) { _property_data = p; } 248 void set_property_data(address p) { _property_data = p; }
249 249
250 SymbolPropertyEntry* next() const { 250 SymbolPropertyEntry* next() const {
251 return (SymbolPropertyEntry*)HashtableEntry::next(); 251 return (SymbolPropertyEntry*)HashtableEntry<Symbol*>::next();
252 } 252 }
253 253
254 SymbolPropertyEntry** next_addr() { 254 SymbolPropertyEntry** next_addr() {
255 return (SymbolPropertyEntry**)HashtableEntry::next_addr(); 255 return (SymbolPropertyEntry**)HashtableEntry<Symbol*>::next_addr();
256 } 256 }
257 257
258 oop* symbol_addr() { return literal_addr(); }
259 oop* property_oop_addr() { return &_property_oop; } 258 oop* property_oop_addr() { return &_property_oop; }
260 259
261 void print_on(outputStream* st) const { 260 void print_on(outputStream* st) const {
262 symbol()->print_value_on(st); 261 symbol()->print_value_on(st);
263 st->print("/mode="INTX_FORMAT, symbol_mode()); 262 st->print("/mode="INTX_FORMAT, symbol_mode());
277 }; 276 };
278 277
279 // A system-internal mapping of symbols to pointers, both managed 278 // A system-internal mapping of symbols to pointers, both managed
280 // and unmanaged. Used to record the auto-generation of each method 279 // and unmanaged. Used to record the auto-generation of each method
281 // MethodHandle.invoke(S)T, for all signatures (S)T. 280 // MethodHandle.invoke(S)T, for all signatures (S)T.
282 class SymbolPropertyTable : public Hashtable { 281 class SymbolPropertyTable : public Hashtable<Symbol*> {
283 friend class VMStructs; 282 friend class VMStructs;
284 private: 283 private:
285 SymbolPropertyEntry* bucket(int i) { 284 SymbolPropertyEntry* bucket(int i) {
286 return (SymbolPropertyEntry*) Hashtable::bucket(i); 285 return (SymbolPropertyEntry*) Hashtable<Symbol*>::bucket(i);
287 } 286 }
288 287
289 // The following method is not MT-safe and must be done under lock. 288 // The following method is not MT-safe and must be done under lock.
290 SymbolPropertyEntry** bucket_addr(int i) { 289 SymbolPropertyEntry** bucket_addr(int i) {
291 return (SymbolPropertyEntry**) Hashtable::bucket_addr(i); 290 return (SymbolPropertyEntry**) Hashtable<Symbol*>::bucket_addr(i);
292 } 291 }
293 292
294 void add_entry(int index, SymbolPropertyEntry* new_entry) { 293 void add_entry(int index, SymbolPropertyEntry* new_entry) {
295 ShouldNotReachHere(); 294 ShouldNotReachHere();
296 } 295 }
297 void set_entry(int index, SymbolPropertyEntry* new_entry) { 296 void set_entry(int index, SymbolPropertyEntry* new_entry) {
298 ShouldNotReachHere(); 297 ShouldNotReachHere();
299 } 298 }
300 299
301 SymbolPropertyEntry* new_entry(unsigned int hash, symbolOop symbol, intptr_t symbol_mode) { 300 SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
302 SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol); 301 SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*>::new_entry(hash, symbol);
302 // Hashtable with Symbol* literal must increment and decrement refcount.
303 symbol->increment_refcount();
303 entry->set_symbol_mode(symbol_mode); 304 entry->set_symbol_mode(symbol_mode);
304 entry->set_property_oop(NULL); 305 entry->set_property_oop(NULL);
305 entry->set_property_data(NULL); 306 entry->set_property_data(NULL);
306 return entry; 307 return entry;
307 } 308 }
309 public: 310 public:
310 SymbolPropertyTable(int table_size); 311 SymbolPropertyTable(int table_size);
311 SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries); 312 SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
312 313
313 void free_entry(SymbolPropertyEntry* entry) { 314 void free_entry(SymbolPropertyEntry* entry) {
314 Hashtable::free_entry(entry); 315 // decrement Symbol refcount here because hashtable doesn't.
315 } 316 entry->literal()->decrement_refcount();
316 317 Hashtable<Symbol*>::free_entry(entry);
317 unsigned int compute_hash(symbolHandle sym, intptr_t symbol_mode) { 318 }
319
320 unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
318 // Use the regular identity_hash. 321 // Use the regular identity_hash.
319 return Hashtable::compute_hash(sym) ^ symbol_mode; 322 return Hashtable<Symbol*>::compute_hash(sym) ^ symbol_mode;
320 } 323 }
321 324
322 int index_for(symbolHandle name, intptr_t symbol_mode) { 325 int index_for(Symbol* name, intptr_t symbol_mode) {
323 return hash_to_index(compute_hash(name, symbol_mode)); 326 return hash_to_index(compute_hash(name, symbol_mode));
324 } 327 }
325 328
326 // need not be locked; no state change 329 // need not be locked; no state change
327 SymbolPropertyEntry* find_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode); 330 SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
328 331
329 // must be done under SystemDictionary_lock 332 // must be done under SystemDictionary_lock
330 SymbolPropertyEntry* add_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode); 333 SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
331 334
332 // GC support 335 // GC support
333 void oops_do(OopClosure* f); 336 void oops_do(OopClosure* f);
334 void methods_do(void f(methodOop)); 337 void methods_do(void f(methodOop));
335 338
341 #ifndef PRODUCT 344 #ifndef PRODUCT
342 void print(); 345 void print();
343 #endif 346 #endif
344 void verify(); 347 void verify();
345 }; 348 };
346
347
348 #endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP 349 #endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP