comparison src/share/vm/classfile/dictionary.hpp @ 12840:aa6f2ea19d8f

Merge
author jcoomes
date Fri, 11 Oct 2013 08:27:21 -0700
parents 190899198332 82af7d7a0128
children 78bbf4d43a14
comparison
equal deleted inserted replaced
12829:c01f4910f5f5 12840:aa6f2ea19d8f
25 #ifndef SHARE_VM_CLASSFILE_DICTIONARY_HPP 25 #ifndef SHARE_VM_CLASSFILE_DICTIONARY_HPP
26 #define SHARE_VM_CLASSFILE_DICTIONARY_HPP 26 #define SHARE_VM_CLASSFILE_DICTIONARY_HPP
27 27
28 #include "classfile/systemDictionary.hpp" 28 #include "classfile/systemDictionary.hpp"
29 #include "oops/instanceKlass.hpp" 29 #include "oops/instanceKlass.hpp"
30 #include "oops/oop.hpp" 30 #include "oops/oop.inline.hpp"
31 #include "utilities/hashtable.hpp" 31 #include "utilities/hashtable.hpp"
32 32
33 class DictionaryEntry; 33 class DictionaryEntry;
34 class PSPromotionManager; 34 class PSPromotionManager;
35 class ProtectionDomainCacheTable;
36 class ProtectionDomainCacheEntry;
37 class BoolObjectClosure;
35 38
36 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 39 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 // The data structure for the system dictionary (and the shared system 40 // The data structure for the system dictionary (and the shared system
38 // dictionary). 41 // dictionary).
39 42
43 // current iteration index. 46 // current iteration index.
44 static int _current_class_index; 47 static int _current_class_index;
45 // pointer to the current hash table entry. 48 // pointer to the current hash table entry.
46 static DictionaryEntry* _current_class_entry; 49 static DictionaryEntry* _current_class_entry;
47 50
51 ProtectionDomainCacheTable* _pd_cache_table;
52
48 DictionaryEntry* get_entry(int index, unsigned int hash, 53 DictionaryEntry* get_entry(int index, unsigned int hash,
49 Symbol* name, ClassLoaderData* loader_data); 54 Symbol* name, ClassLoaderData* loader_data);
50 55
51 DictionaryEntry* bucket(int i) { 56 DictionaryEntry* bucket(int i) {
52 return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i); 57 return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i);
91 void classes_do(void f(Klass*, TRAPS), TRAPS); 96 void classes_do(void f(Klass*, TRAPS), TRAPS);
92 void classes_do(void f(Klass*, ClassLoaderData*)); 97 void classes_do(void f(Klass*, ClassLoaderData*));
93 98
94 void methods_do(void f(Method*)); 99 void methods_do(void f(Method*));
95 100
101 void unlink(BoolObjectClosure* is_alive);
96 102
97 // Classes loaded by the bootstrap loader are always strongly reachable. 103 // Classes loaded by the bootstrap loader are always strongly reachable.
98 // If we're not doing class unloading, all classes are strongly reachable. 104 // If we're not doing class unloading, all classes are strongly reachable.
99 static bool is_strongly_reachable(ClassLoaderData* loader_data, Klass* klass) { 105 static bool is_strongly_reachable(ClassLoaderData* loader_data, Klass* klass) {
100 assert (klass != NULL, "should have non-null klass"); 106 assert (klass != NULL, "should have non-null klass");
116 Handle protection_domain, TRAPS); 122 Handle protection_domain, TRAPS);
117 123
118 // Sharing support 124 // Sharing support
119 void reorder_dictionary(); 125 void reorder_dictionary();
120 126
127 ProtectionDomainCacheEntry* cache_get(oop protection_domain);
121 128
122 #ifndef PRODUCT 129 #ifndef PRODUCT
123 void print(); 130 void print();
124 #endif 131 #endif
125 void verify(); 132 void verify();
126 }; 133 };
127 134
128 // The following classes can be in dictionary.cpp, but we need these 135 // The following classes can be in dictionary.cpp, but we need these
129 // to be in header file so that SA's vmStructs can access. 136 // to be in header file so that SA's vmStructs can access them.
137 class ProtectionDomainCacheEntry : public HashtableEntry<oop, mtClass> {
138 friend class VMStructs;
139 private:
140 // Flag indicating whether this protection domain entry is strongly reachable.
141 // Used during iterating over the system dictionary to remember oops that need
142 // to be updated.
143 bool _strongly_reachable;
144 public:
145 oop protection_domain() { return literal(); }
146
147 void init() {
148 _strongly_reachable = false;
149 }
150
151 ProtectionDomainCacheEntry* next() {
152 return (ProtectionDomainCacheEntry*)HashtableEntry<oop, mtClass>::next();
153 }
154
155 ProtectionDomainCacheEntry** next_addr() {
156 return (ProtectionDomainCacheEntry**)HashtableEntry<oop, mtClass>::next_addr();
157 }
158
159 void oops_do(OopClosure* f) {
160 f->do_oop(literal_addr());
161 }
162
163 void set_strongly_reachable() { _strongly_reachable = true; }
164 bool is_strongly_reachable() { return _strongly_reachable; }
165 void reset_strongly_reachable() { _strongly_reachable = false; }
166
167 void print() PRODUCT_RETURN;
168 void verify();
169 };
170
171 // The ProtectionDomainCacheTable contains all protection domain oops. The system
172 // dictionary entries reference its entries instead of having references to oops
173 // directly.
174 // This is used to speed up system dictionary iteration: the oops in the
175 // protection domain are the only ones referring the Java heap. So when there is
176 // need to update these, instead of going over every entry of the system dictionary,
177 // we only need to iterate over this set.
178 // The amount of different protection domains used is typically magnitudes smaller
179 // than the number of system dictionary entries (loaded classes).
180 class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> {
181 friend class VMStructs;
182 private:
183 ProtectionDomainCacheEntry* bucket(int i) {
184 return (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::bucket(i);
185 }
186
187 // The following method is not MT-safe and must be done under lock.
188 ProtectionDomainCacheEntry** bucket_addr(int i) {
189 return (ProtectionDomainCacheEntry**) Hashtable<oop, mtClass>::bucket_addr(i);
190 }
191
192 ProtectionDomainCacheEntry* new_entry(unsigned int hash, oop protection_domain) {
193 ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::new_entry(hash, protection_domain);
194 entry->init();
195 return entry;
196 }
197
198 static unsigned int compute_hash(oop protection_domain) {
199 return (unsigned int)(protection_domain->identity_hash());
200 }
201
202 int index_for(oop protection_domain) {
203 return hash_to_index(compute_hash(protection_domain));
204 }
205
206 ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, oop protection_domain);
207 ProtectionDomainCacheEntry* find_entry(int index, oop protection_domain);
208
209 public:
210
211 ProtectionDomainCacheTable(int table_size);
212
213 ProtectionDomainCacheEntry* get(oop protection_domain);
214 void free(ProtectionDomainCacheEntry* entry);
215
216 void unlink(BoolObjectClosure* cl);
217
218 // GC support
219 void oops_do(OopClosure* f);
220 void always_strong_oops_do(OopClosure* f);
221
222 static uint bucket_size();
223
224 void print() PRODUCT_RETURN;
225 void verify();
226 };
227
130 228
131 class ProtectionDomainEntry :public CHeapObj<mtClass> { 229 class ProtectionDomainEntry :public CHeapObj<mtClass> {
132 friend class VMStructs; 230 friend class VMStructs;
133 public: 231 public:
134 ProtectionDomainEntry* _next; 232 ProtectionDomainEntry* _next;
135 oop _protection_domain; 233 ProtectionDomainCacheEntry* _pd_cache;
136 234
137 ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) { 235 ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) {
138 _protection_domain = protection_domain; 236 _pd_cache = pd_cache;
139 _next = next; 237 _next = next;
140 } 238 }
141 239
142 ProtectionDomainEntry* next() { return _next; } 240 ProtectionDomainEntry* next() { return _next; }
143 oop protection_domain() { return _protection_domain; } 241 oop protection_domain() { return _pd_cache->protection_domain(); }
144 }; 242 };
145 243
146 // An entry in the system dictionary, this describes a class as 244 // An entry in the system dictionary, this describes a class as
147 // { Klass*, loader, protection_domain }. 245 // { Klass*, loader, protection_domain }.
148 246
149 class DictionaryEntry : public HashtableEntry<Klass*, mtClass> { 247 class DictionaryEntry : public HashtableEntry<Klass*, mtClass> {
150 friend class VMStructs; 248 friend class VMStructs;
151 private: 249 private:
152 // Contains the set of approved protection domains that can access 250 // Contains the set of approved protection domains that can access
153 // this system dictionary entry. 251 // this system dictionary entry.
252 //
253 // This protection domain set is a set of tuples:
254 //
255 // (InstanceKlass C, initiating class loader ICL, Protection Domain PD)
256 //
257 // [Note that C.protection_domain(), which is stored in the java.lang.Class
258 // mirror of C, is NOT the same as PD]
259 //
260 // If such an entry (C, ICL, PD) exists in the table, it means that
261 // it is okay for a class Foo to reference C, where
262 //
263 // Foo.protection_domain() == PD, and
264 // Foo's defining class loader == ICL
265 //
266 // The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()
267 // It is essentially a cache to avoid repeated Java up-calls to
268 // ClassLoader.checkPackageAccess().
269 //
154 ProtectionDomainEntry* _pd_set; 270 ProtectionDomainEntry* _pd_set;
155 ClassLoaderData* _loader_data; 271 ClassLoaderData* _loader_data;
156 272
157 public: 273 public:
158 // Tells whether a protection is in the approved set. 274 // Tells whether a protection is in the approved set.
159 bool contains_protection_domain(oop protection_domain) const; 275 bool contains_protection_domain(oop protection_domain) const;
160 // Adds a protection domain to the approved set. 276 // Adds a protection domain to the approved set.
161 void add_protection_domain(oop protection_domain); 277 void add_protection_domain(Dictionary* dict, oop protection_domain);
162 278
163 Klass* klass() const { return (Klass*)literal(); } 279 Klass* klass() const { return (Klass*)literal(); }
164 Klass** klass_addr() { return (Klass**)literal_addr(); } 280 Klass** klass_addr() { return (Klass**)literal_addr(); }
165 281
166 DictionaryEntry* next() const { 282 DictionaryEntry* next() const {
187 return protection_domain() == NULL 303 return protection_domain() == NULL
188 ? true 304 ? true
189 : contains_protection_domain(protection_domain()); 305 : contains_protection_domain(protection_domain());
190 } 306 }
191 307
192 308 void set_strongly_reachable() {
193 void protection_domain_set_oops_do(OopClosure* f) {
194 for (ProtectionDomainEntry* current = _pd_set; 309 for (ProtectionDomainEntry* current = _pd_set;
195 current != NULL; 310 current != NULL;
196 current = current->_next) { 311 current = current->_next) {
197 f->do_oop(&(current->_protection_domain)); 312 current->_pd_cache->set_strongly_reachable();
198 } 313 }
199 } 314 }
200 315
201 void verify_protection_domain_set() { 316 void verify_protection_domain_set() {
202 for (ProtectionDomainEntry* current = _pd_set; 317 for (ProtectionDomainEntry* current = _pd_set;
203 current != NULL; 318 current != NULL;
204 current = current->_next) { 319 current = current->_next) {
205 current->_protection_domain->verify(); 320 current->_pd_cache->protection_domain()->verify();
206 } 321 }
207 } 322 }
208 323
209 bool equals(Symbol* class_name, ClassLoaderData* loader_data) const { 324 bool equals(Symbol* class_name, ClassLoaderData* loader_data) const {
210 Klass* klass = (Klass*)literal(); 325 Klass* klass = (Klass*)literal();