Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/dictionary.hpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | d2a62e0f25eb |
children | 43083e670adf |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
29 #include "oops/instanceKlass.hpp" | 29 #include "oops/instanceKlass.hpp" |
30 #include "oops/oop.hpp" | 30 #include "oops/oop.hpp" |
31 #include "utilities/hashtable.hpp" | 31 #include "utilities/hashtable.hpp" |
32 | 32 |
33 class DictionaryEntry; | 33 class DictionaryEntry; |
34 class PSPromotionManager; | |
34 | 35 |
35 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 36 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
36 // The data structure for the system dictionary (and the shared system | 37 // The data structure for the system dictionary (and the shared system |
37 // dictionary). | 38 // dictionary). |
38 | 39 |
39 class Dictionary : public TwoOopHashtable<klassOop, mtClass> { | 40 class Dictionary : public TwoOopHashtable<Klass*, mtClass> { |
40 friend class VMStructs; | 41 friend class VMStructs; |
41 private: | 42 private: |
42 // current iteration index. | 43 // current iteration index. |
43 static int _current_class_index; | 44 static int _current_class_index; |
44 // pointer to the current hash table entry. | 45 // pointer to the current hash table entry. |
45 static DictionaryEntry* _current_class_entry; | 46 static DictionaryEntry* _current_class_entry; |
46 | 47 |
47 DictionaryEntry* get_entry(int index, unsigned int hash, | 48 DictionaryEntry* get_entry(int index, unsigned int hash, |
48 Symbol* name, Handle loader); | 49 Symbol* name, ClassLoaderData* loader_data); |
49 | 50 |
50 DictionaryEntry* bucket(int i) { | 51 DictionaryEntry* bucket(int i) { |
51 return (DictionaryEntry*)Hashtable<klassOop, mtClass>::bucket(i); | 52 return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i); |
52 } | 53 } |
53 | 54 |
54 // The following method is not MT-safe and must be done under lock. | 55 // The following method is not MT-safe and must be done under lock. |
55 DictionaryEntry** bucket_addr(int i) { | 56 DictionaryEntry** bucket_addr(int i) { |
56 return (DictionaryEntry**)Hashtable<klassOop, mtClass>::bucket_addr(i); | 57 return (DictionaryEntry**)Hashtable<Klass*, mtClass>::bucket_addr(i); |
57 } | 58 } |
58 | 59 |
59 void add_entry(int index, DictionaryEntry* new_entry) { | 60 void add_entry(int index, DictionaryEntry* new_entry) { |
60 Hashtable<klassOop, mtClass>::add_entry(index, (HashtableEntry<oop, mtClass>*)new_entry); | 61 Hashtable<Klass*, mtClass>::add_entry(index, (HashtableEntry<Klass*, mtClass>*)new_entry); |
61 } | 62 } |
62 | |
63 | 63 |
64 public: | 64 public: |
65 Dictionary(int table_size); | 65 Dictionary(int table_size); |
66 Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries); | 66 Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries); |
67 | 67 |
68 DictionaryEntry* new_entry(unsigned int hash, klassOop klass, oop loader); | 68 DictionaryEntry* new_entry(unsigned int hash, Klass* klass, ClassLoaderData* loader_data); |
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(Symbol* class_name, Handle class_loader,KlassHandle obj); | 74 void add_klass(Symbol* class_name, ClassLoaderData* loader_data,KlassHandle obj); |
75 | 75 |
76 klassOop find_class(int index, unsigned int hash, | 76 Klass* find_class(int index, unsigned int hash, |
77 Symbol* name, Handle loader); | 77 Symbol* name, ClassLoaderData* loader_data); |
78 | 78 |
79 klassOop find_shared_class(int index, unsigned int hash, Symbol* name); | 79 Klass* 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 Klass* try_get_next_class(); |
83 | 83 |
84 // GC support | 84 // GC support |
85 | |
86 void oops_do(OopClosure* f); | 85 void oops_do(OopClosure* f); |
87 void always_strong_classes_do(OopClosure* blk); | 86 void always_strong_oops_do(OopClosure* blk); |
88 void classes_do(void f(klassOop)); | 87 |
89 void classes_do(void f(klassOop, TRAPS), TRAPS); | 88 void always_strong_classes_do(KlassClosure* closure); |
90 void classes_do(void f(klassOop, oop)); | 89 |
91 void classes_do(void f(klassOop, oop, TRAPS), TRAPS); | 90 void classes_do(void f(Klass*)); |
92 | 91 void classes_do(void f(Klass*, TRAPS), TRAPS); |
93 void methods_do(void f(methodOop)); | 92 void classes_do(void f(Klass*, ClassLoaderData*)); |
93 void classes_do(void f(Klass*, ClassLoaderData*, TRAPS), TRAPS); | |
94 | |
95 void methods_do(void f(Method*)); | |
94 | 96 |
95 | 97 |
96 // Classes loaded by the bootstrap loader are always strongly reachable. | 98 // Classes loaded by the bootstrap loader are always strongly reachable. |
97 // If we're not doing class unloading, all classes are strongly reachable. | 99 // If we're not doing class unloading, all classes are strongly reachable. |
98 static bool is_strongly_reachable(oop class_loader, klassOop klass) { | 100 static bool is_strongly_reachable(ClassLoaderData* loader_data, Klass* klass) { |
99 assert (klass != NULL, "should have non-null klass"); | 101 assert (klass != NULL, "should have non-null klass"); |
100 return (class_loader == NULL || !ClassUnloading); | 102 return (loader_data->is_the_null_class_loader_data() || !ClassUnloading); |
101 } | 103 } |
102 | 104 |
103 // Unload (that is, break root links to) all unmarked classes and | 105 // Unload (that is, break root links to) all unmarked classes and |
104 // loaders. Returns "true" iff something was unloaded. | 106 // loaders. Returns "true" iff something was unloaded. |
105 bool do_unloading(BoolObjectClosure* is_alive); | 107 bool do_unloading(); |
106 | 108 |
107 // Protection domains | 109 // Protection domains |
108 klassOop find(int index, unsigned int hash, Symbol* name, | 110 Klass* find(int index, unsigned int hash, Symbol* name, |
109 Handle loader, Handle protection_domain, TRAPS); | 111 ClassLoaderData* loader_data, Handle protection_domain, TRAPS); |
110 bool is_valid_protection_domain(int index, unsigned int hash, | 112 bool is_valid_protection_domain(int index, unsigned int hash, |
111 Symbol* name, Handle class_loader, | 113 Symbol* name, ClassLoaderData* loader_data, |
112 Handle protection_domain); | 114 Handle protection_domain); |
113 void add_protection_domain(int index, unsigned int hash, | 115 void add_protection_domain(int index, unsigned int hash, |
114 instanceKlassHandle klass, Handle loader, | 116 instanceKlassHandle klass, ClassLoaderData* loader_data, |
115 Handle protection_domain, TRAPS); | 117 Handle protection_domain, TRAPS); |
116 | 118 |
117 // Sharing support | 119 // Sharing support |
118 void dump(SerializeOopClosure* soc); | |
119 void restore(SerializeOopClosure* soc); | |
120 void reorder_dictionary(); | 120 void reorder_dictionary(); |
121 | 121 |
122 | 122 |
123 #ifndef PRODUCT | 123 #ifndef PRODUCT |
124 void print(); | 124 void print(); |
143 ProtectionDomainEntry* next() { return _next; } | 143 ProtectionDomainEntry* next() { return _next; } |
144 oop protection_domain() { return _protection_domain; } | 144 oop protection_domain() { return _protection_domain; } |
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 // { Klass*, loader, protection_domain }. |
149 | 149 |
150 class DictionaryEntry : public HashtableEntry<klassOop, mtClass> { | 150 class DictionaryEntry : public HashtableEntry<Klass*, mtClass> { |
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; |
156 oop _loader; | 156 ClassLoaderData* _loader_data; |
157 | |
158 | 157 |
159 public: | 158 public: |
160 // Tells whether a protection is in the approved set. | 159 // Tells whether a protection is in the approved set. |
161 bool contains_protection_domain(oop protection_domain) const; | 160 bool contains_protection_domain(oop protection_domain) const; |
162 // Adds a protection domain to the approved set. | 161 // Adds a protection domain to the approved set. |
163 void add_protection_domain(oop protection_domain); | 162 void add_protection_domain(oop protection_domain); |
164 | 163 |
165 klassOop klass() const { return (klassOop)literal(); } | 164 Klass* klass() const { return (Klass*)literal(); } |
166 klassOop* klass_addr() { return (klassOop*)literal_addr(); } | 165 Klass** klass_addr() { return (Klass**)literal_addr(); } |
167 | 166 |
168 DictionaryEntry* next() const { | 167 DictionaryEntry* next() const { |
169 return (DictionaryEntry*)HashtableEntry<klassOop, mtClass>::next(); | 168 return (DictionaryEntry*)HashtableEntry<Klass*, mtClass>::next(); |
170 } | 169 } |
171 | 170 |
172 DictionaryEntry** next_addr() { | 171 DictionaryEntry** next_addr() { |
173 return (DictionaryEntry**)HashtableEntry<klassOop, mtClass>::next_addr(); | 172 return (DictionaryEntry**)HashtableEntry<Klass*, mtClass>::next_addr(); |
174 } | 173 } |
175 | 174 |
176 oop loader() const { return _loader; } | 175 ClassLoaderData* loader_data() const { return _loader_data; } |
177 void set_loader(oop loader) { _loader = loader; } | 176 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; } |
178 oop* loader_addr() { return &_loader; } | |
179 | 177 |
180 ProtectionDomainEntry* pd_set() const { return _pd_set; } | 178 ProtectionDomainEntry* pd_set() const { return _pd_set; } |
181 void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; } | 179 void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; } |
182 | 180 |
183 bool has_protection_domain() { return _pd_set != NULL; } | 181 bool has_protection_domain() { return _pd_set != NULL; } |
207 current = current->_next) { | 205 current = current->_next) { |
208 current->_protection_domain->verify(); | 206 current->_protection_domain->verify(); |
209 } | 207 } |
210 } | 208 } |
211 | 209 |
212 bool equals(Symbol* class_name, oop class_loader) const { | 210 bool equals(Symbol* class_name, ClassLoaderData* loader_data) const { |
213 klassOop klass = (klassOop)literal(); | 211 Klass* klass = (Klass*)literal(); |
214 return (instanceKlass::cast(klass)->name() == class_name && | 212 return (InstanceKlass::cast(klass)->name() == class_name && |
215 _loader == class_loader); | 213 _loader_data == loader_data); |
216 } | 214 } |
217 | 215 |
218 void print() { | 216 void print() { |
219 int count = 0; | 217 int count = 0; |
220 for (ProtectionDomainEntry* current = _pd_set; | 218 for (ProtectionDomainEntry* current = _pd_set; |
230 // to a managed and an unmanaged pointer. | 228 // to a managed and an unmanaged pointer. |
231 class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> { | 229 class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> { |
232 friend class VMStructs; | 230 friend class VMStructs; |
233 private: | 231 private: |
234 intptr_t _symbol_mode; // secondary key | 232 intptr_t _symbol_mode; // secondary key |
235 oop _property_oop; | 233 Method* _method; |
236 address _property_data; | 234 oop _method_type; |
237 | 235 |
238 public: | 236 public: |
239 Symbol* symbol() const { return literal(); } | 237 Symbol* symbol() const { return literal(); } |
240 | 238 |
241 intptr_t symbol_mode() const { return _symbol_mode; } | 239 intptr_t symbol_mode() const { return _symbol_mode; } |
242 void set_symbol_mode(intptr_t m) { _symbol_mode = m; } | 240 void set_symbol_mode(intptr_t m) { _symbol_mode = m; } |
243 | 241 |
244 oop property_oop() const { return _property_oop; } | 242 Method* method() const { return _method; } |
245 void set_property_oop(oop p) { _property_oop = p; } | 243 void set_method(Method* p) { _method = p; } |
246 | 244 |
247 address property_data() const { return _property_data; } | 245 oop method_type() const { return _method_type; } |
248 void set_property_data(address p) { _property_data = p; } | 246 oop* method_type_addr() { return &_method_type; } |
247 void set_method_type(oop p) { _method_type = p; } | |
249 | 248 |
250 SymbolPropertyEntry* next() const { | 249 SymbolPropertyEntry* next() const { |
251 return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next(); | 250 return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next(); |
252 } | 251 } |
253 | 252 |
254 SymbolPropertyEntry** next_addr() { | 253 SymbolPropertyEntry** next_addr() { |
255 return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr(); | 254 return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr(); |
256 } | 255 } |
257 | |
258 oop* property_oop_addr() { return &_property_oop; } | |
259 | 256 |
260 void print_on(outputStream* st) const { | 257 void print_on(outputStream* st) const { |
261 symbol()->print_value_on(st); | 258 symbol()->print_value_on(st); |
262 st->print("/mode="INTX_FORMAT, symbol_mode()); | 259 st->print("/mode="INTX_FORMAT, symbol_mode()); |
263 st->print(" -> "); | 260 st->print(" -> "); |
264 bool printed = false; | 261 bool printed = false; |
265 if (property_oop() != NULL) { | 262 if (method() != NULL) { |
266 property_oop()->print_value_on(st); | 263 method()->print_value_on(st); |
267 printed = true; | 264 printed = true; |
268 } | 265 } |
269 if (property_data() != NULL) { | 266 if (method_type() != NULL) { |
270 if (printed) st->print(" and "); | 267 if (printed) st->print(" and "); |
271 st->print(INTPTR_FORMAT, property_data()); | 268 st->print(INTPTR_FORMAT, method_type()); |
272 printed = true; | 269 printed = true; |
273 } | 270 } |
274 st->print_cr(printed ? "" : "(empty)"); | 271 st->print_cr(printed ? "" : "(empty)"); |
275 } | 272 } |
276 }; | 273 }; |
300 SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) { | 297 SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) { |
301 SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol); | 298 SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol); |
302 // Hashtable with Symbol* literal must increment and decrement refcount. | 299 // Hashtable with Symbol* literal must increment and decrement refcount. |
303 symbol->increment_refcount(); | 300 symbol->increment_refcount(); |
304 entry->set_symbol_mode(symbol_mode); | 301 entry->set_symbol_mode(symbol_mode); |
305 entry->set_property_oop(NULL); | 302 entry->set_method(NULL); |
306 entry->set_property_data(NULL); | 303 entry->set_method_type(NULL); |
307 return entry; | 304 return entry; |
308 } | 305 } |
309 | 306 |
310 public: | 307 public: |
311 SymbolPropertyTable(int table_size); | 308 SymbolPropertyTable(int table_size); |
332 // must be done under SystemDictionary_lock | 329 // must be done under SystemDictionary_lock |
333 SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode); | 330 SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode); |
334 | 331 |
335 // GC support | 332 // GC support |
336 void oops_do(OopClosure* f); | 333 void oops_do(OopClosure* f); |
337 void methods_do(void f(methodOop)); | 334 |
335 void methods_do(void f(Method*)); | |
338 | 336 |
339 // Sharing support | 337 // Sharing support |
340 void dump(SerializeOopClosure* soc); | |
341 void restore(SerializeOopClosure* soc); | |
342 void reorder_dictionary(); | 338 void reorder_dictionary(); |
343 | 339 |
344 #ifndef PRODUCT | 340 #ifndef PRODUCT |
345 void print(); | 341 void print(); |
346 #endif | 342 #endif |