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