Mercurial > hg > truffle
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 |