Mercurial > hg > truffle
annotate src/share/vm/classfile/dictionary.cpp @ 3011:f00918f35c7f
inlining and runtime interface related changes:
added codeSize() and compilerStorage() to RiMethod
HotSpotMethodResolved uses reflective methods instead of vmIds and survives compilations
HotSpotResolvedType.isInitialized not represented as field (can change)
inlining stores graphs into method objects and reuses them
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Thu, 16 Jun 2011 20:36:17 +0200 |
parents | 1d1603768966 |
children | b2cd0ee8f778 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/dictionary.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "oops/oop.inline.hpp" | |
29 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
30 #include "services/classLoadingService.hpp" | |
31 #include "utilities/hashtable.inline.hpp" | |
0 | 32 |
33 | |
34 DictionaryEntry* Dictionary::_current_class_entry = NULL; | |
35 int Dictionary::_current_class_index = 0; | |
36 | |
37 | |
38 Dictionary::Dictionary(int table_size) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
39 : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry)) { |
0 | 40 _current_class_index = 0; |
41 _current_class_entry = NULL; | |
42 }; | |
43 | |
44 | |
45 | |
46 Dictionary::Dictionary(int table_size, HashtableBucket* t, | |
47 int number_of_entries) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
48 : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry), t, number_of_entries) { |
0 | 49 _current_class_index = 0; |
50 _current_class_entry = NULL; | |
51 }; | |
52 | |
53 | |
54 DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass, | |
55 oop loader) { | |
56 DictionaryEntry* entry; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
57 entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(hash, klass); |
0 | 58 entry->set_loader(loader); |
59 entry->set_pd_set(NULL); | |
60 return entry; | |
61 } | |
62 | |
63 | |
64 DictionaryEntry* Dictionary::new_entry() { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
65 DictionaryEntry* entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(0L, NULL); |
0 | 66 entry->set_loader(NULL); |
67 entry->set_pd_set(NULL); | |
68 return entry; | |
69 } | |
70 | |
71 | |
72 void Dictionary::free_entry(DictionaryEntry* entry) { | |
73 // avoid recursion when deleting linked list | |
74 while (entry->pd_set() != NULL) { | |
75 ProtectionDomainEntry* to_delete = entry->pd_set(); | |
76 entry->set_pd_set(to_delete->next()); | |
77 delete to_delete; | |
78 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
79 Hashtable<klassOop>::free_entry(entry); |
0 | 80 } |
81 | |
82 | |
83 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { | |
84 #ifdef ASSERT | |
85 if (protection_domain == instanceKlass::cast(klass())->protection_domain()) { | |
86 // Ensure this doesn't show up in the pd_set (invariant) | |
87 bool in_pd_set = false; | |
88 for (ProtectionDomainEntry* current = _pd_set; | |
89 current != NULL; | |
90 current = current->next()) { | |
91 if (current->protection_domain() == protection_domain) { | |
92 in_pd_set = true; | |
93 break; | |
94 } | |
95 } | |
96 if (in_pd_set) { | |
97 assert(false, "A klass's protection domain should not show up " | |
98 "in its sys. dict. PD set"); | |
99 } | |
100 } | |
101 #endif /* ASSERT */ | |
102 | |
103 if (protection_domain == instanceKlass::cast(klass())->protection_domain()) { | |
104 // Succeeds trivially | |
105 return true; | |
106 } | |
107 | |
108 for (ProtectionDomainEntry* current = _pd_set; | |
109 current != NULL; | |
110 current = current->next()) { | |
111 if (current->protection_domain() == protection_domain) return true; | |
112 } | |
113 return false; | |
114 } | |
115 | |
116 | |
117 void DictionaryEntry::add_protection_domain(oop protection_domain) { | |
118 assert_locked_or_safepoint(SystemDictionary_lock); | |
119 if (!contains_protection_domain(protection_domain)) { | |
120 ProtectionDomainEntry* new_head = | |
121 new ProtectionDomainEntry(protection_domain, _pd_set); | |
122 // Warning: Preserve store ordering. The SystemDictionary is read | |
123 // without locks. The new ProtectionDomainEntry must be | |
124 // complete before other threads can be allowed to see it | |
125 // via a store to _pd_set. | |
126 OrderAccess::release_store_ptr(&_pd_set, new_head); | |
127 } | |
128 if (TraceProtectionDomainVerification && WizardMode) { | |
129 print(); | |
130 } | |
131 } | |
132 | |
133 | |
134 bool Dictionary::do_unloading(BoolObjectClosure* is_alive) { | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
710
diff
changeset
|
135 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
0 | 136 bool class_was_unloaded = false; |
137 int index = 0; // Defined here for portability! Do not move | |
138 | |
139 // Remove unloadable entries and classes from system dictionary | |
140 // The placeholder array has been handled in always_strong_oops_do. | |
141 DictionaryEntry* probe = NULL; | |
142 for (index = 0; index < table_size(); index++) { | |
143 for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) { | |
144 probe = *p; | |
145 klassOop e = probe->klass(); | |
146 oop class_loader = probe->loader(); | |
147 | |
148 instanceKlass* ik = instanceKlass::cast(e); | |
149 if (ik->previous_versions() != NULL) { | |
150 // This klass has previous versions so see what we can cleanup | |
151 // while it is safe to do so. | |
152 | |
153 int gc_count = 0; // leave debugging breadcrumbs | |
154 int live_count = 0; | |
155 | |
156 // RC_TRACE macro has an embedded ResourceMark | |
157 RC_TRACE(0x00000200, ("unload: %s: previous version length=%d", | |
158 ik->external_name(), ik->previous_versions()->length())); | |
159 | |
160 for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) { | |
161 // check the previous versions array for GC'ed weak refs | |
162 PreviousVersionNode * pv_node = ik->previous_versions()->at(i); | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
163 jobject cp_ref = pv_node->prev_constant_pool(); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
164 assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); |
0 | 165 if (cp_ref == NULL) { |
166 delete pv_node; | |
167 ik->previous_versions()->remove_at(i); | |
168 // Since we are traversing the array backwards, we don't have to | |
169 // do anything special with the index. | |
170 continue; // robustness | |
171 } | |
172 | |
173 constantPoolOop pvcp = (constantPoolOop)JNIHandles::resolve(cp_ref); | |
174 if (pvcp == NULL) { | |
175 // this entry has been GC'ed so remove it | |
176 delete pv_node; | |
177 ik->previous_versions()->remove_at(i); | |
178 // Since we are traversing the array backwards, we don't have to | |
179 // do anything special with the index. | |
180 gc_count++; | |
181 continue; | |
182 } else { | |
183 RC_TRACE(0x00000200, ("unload: previous version @%d is alive", i)); | |
184 if (is_alive->do_object_b(pvcp)) { | |
185 live_count++; | |
186 } else { | |
187 guarantee(false, "sanity check"); | |
188 } | |
189 } | |
190 | |
191 GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods(); | |
192 if (method_refs != NULL) { | |
193 RC_TRACE(0x00000200, ("unload: previous methods length=%d", | |
194 method_refs->length())); | |
195 for (int j = method_refs->length() - 1; j >= 0; j--) { | |
196 jweak method_ref = method_refs->at(j); | |
197 assert(method_ref != NULL, "weak method ref was unexpectedly cleared"); | |
198 if (method_ref == NULL) { | |
199 method_refs->remove_at(j); | |
200 // Since we are traversing the array backwards, we don't have to | |
201 // do anything special with the index. | |
202 continue; // robustness | |
203 } | |
204 | |
205 methodOop method = (methodOop)JNIHandles::resolve(method_ref); | |
206 if (method == NULL) { | |
207 // this method entry has been GC'ed so remove it | |
208 JNIHandles::destroy_weak_global(method_ref); | |
209 method_refs->remove_at(j); | |
210 } else { | |
211 // RC_TRACE macro has an embedded ResourceMark | |
212 RC_TRACE(0x00000200, | |
213 ("unload: %s(%s): prev method @%d in version @%d is alive", | |
214 method->name()->as_C_string(), | |
215 method->signature()->as_C_string(), j, i)); | |
216 } | |
217 } | |
218 } | |
219 } | |
220 assert(ik->previous_versions()->length() == live_count, "sanity check"); | |
221 RC_TRACE(0x00000200, | |
222 ("unload: previous version stats: live=%d, GC'ed=%d", live_count, | |
223 gc_count)); | |
224 } | |
225 | |
226 // Non-unloadable classes were handled in always_strong_oops_do | |
227 if (!is_strongly_reachable(class_loader, e)) { | |
228 // Entry was not visited in phase1 (negated test from phase1) | |
229 assert(class_loader != NULL, "unloading entry with null class loader"); | |
230 oop k_def_class_loader = ik->class_loader(); | |
231 | |
232 // Do we need to delete this system dictionary entry? | |
233 bool purge_entry = false; | |
234 | |
235 // Do we need to delete this system dictionary entry? | |
236 if (!is_alive->do_object_b(class_loader)) { | |
237 // If the loader is not live this entry should always be | |
238 // removed (will never be looked up again). Note that this is | |
239 // not the same as unloading the referred class. | |
240 if (k_def_class_loader == class_loader) { | |
241 // This is the defining entry, so the referred class is about | |
242 // to be unloaded. | |
243 // Notify the debugger and clean up the class. | |
244 guarantee(!is_alive->do_object_b(e), | |
245 "klass should not be live if defining loader is not"); | |
246 class_was_unloaded = true; | |
247 // notify the debugger | |
248 if (JvmtiExport::should_post_class_unload()) { | |
249 JvmtiExport::post_class_unload(ik->as_klassOop()); | |
250 } | |
251 | |
252 // notify ClassLoadingService of class unload | |
253 ClassLoadingService::notify_class_unloaded(ik); | |
254 | |
255 // Clean up C heap | |
256 ik->release_C_heap_structures(); | |
257 } | |
258 // Also remove this system dictionary entry. | |
259 purge_entry = true; | |
260 | |
261 } else { | |
262 // The loader in this entry is alive. If the klass is dead, | |
263 // the loader must be an initiating loader (rather than the | |
264 // defining loader). Remove this entry. | |
265 if (!is_alive->do_object_b(e)) { | |
266 guarantee(!is_alive->do_object_b(k_def_class_loader), | |
267 "defining loader should not be live if klass is not"); | |
268 // If we get here, the class_loader must not be the defining | |
269 // loader, it must be an initiating one. | |
270 assert(k_def_class_loader != class_loader, | |
271 "cannot have live defining loader and unreachable klass"); | |
272 | |
273 // Loader is live, but class and its defining loader are dead. | |
274 // Remove the entry. The class is going away. | |
275 purge_entry = true; | |
276 } | |
277 } | |
278 | |
279 if (purge_entry) { | |
280 *p = probe->next(); | |
281 if (probe == _current_class_entry) { | |
282 _current_class_entry = NULL; | |
283 } | |
284 free_entry(probe); | |
285 continue; | |
286 } | |
287 } | |
288 p = probe->next_addr(); | |
289 } | |
290 } | |
291 return class_was_unloaded; | |
292 } | |
293 | |
294 | |
295 void Dictionary::always_strong_classes_do(OopClosure* blk) { | |
296 // Follow all system classes and temporary placeholders in dictionary | |
297 for (int index = 0; index < table_size(); index++) { | |
298 for (DictionaryEntry *probe = bucket(index); | |
299 probe != NULL; | |
300 probe = probe->next()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
301 klassOop e = probe->klass(); |
0 | 302 oop class_loader = probe->loader(); |
303 if (is_strongly_reachable(class_loader, e)) { | |
304 blk->do_oop((oop*)probe->klass_addr()); | |
305 if (class_loader != NULL) { | |
306 blk->do_oop(probe->loader_addr()); | |
307 } | |
308 probe->protection_domain_set_oops_do(blk); | |
309 } | |
310 } | |
311 } | |
312 } | |
313 | |
314 | |
315 // Just the classes from defining class loaders | |
316 void Dictionary::classes_do(void f(klassOop)) { | |
317 for (int index = 0; index < table_size(); index++) { | |
318 for (DictionaryEntry* probe = bucket(index); | |
319 probe != NULL; | |
320 probe = probe->next()) { | |
321 klassOop k = probe->klass(); | |
322 if (probe->loader() == instanceKlass::cast(k)->class_loader()) { | |
323 f(k); | |
324 } | |
325 } | |
326 } | |
327 } | |
328 | |
329 // Added for initialize_itable_for_klass to handle exceptions | |
330 // Just the classes from defining class loaders | |
331 void Dictionary::classes_do(void f(klassOop, TRAPS), TRAPS) { | |
332 for (int index = 0; index < table_size(); index++) { | |
333 for (DictionaryEntry* probe = bucket(index); | |
334 probe != NULL; | |
335 probe = probe->next()) { | |
336 klassOop k = probe->klass(); | |
337 if (probe->loader() == instanceKlass::cast(k)->class_loader()) { | |
338 f(k, CHECK); | |
339 } | |
340 } | |
341 } | |
342 } | |
343 | |
344 | |
345 // All classes, and their class loaders | |
346 // (added for helpers that use HandleMarks and ResourceMarks) | |
347 // Don't iterate over placeholders | |
348 void Dictionary::classes_do(void f(klassOop, oop, TRAPS), TRAPS) { | |
349 for (int index = 0; index < table_size(); index++) { | |
350 for (DictionaryEntry* probe = bucket(index); | |
351 probe != NULL; | |
352 probe = probe->next()) { | |
353 klassOop k = probe->klass(); | |
354 f(k, probe->loader(), CHECK); | |
355 } | |
356 } | |
357 } | |
358 | |
359 | |
360 // All classes, and their class loaders | |
361 // Don't iterate over placeholders | |
362 void Dictionary::classes_do(void f(klassOop, oop)) { | |
363 for (int index = 0; index < table_size(); index++) { | |
364 for (DictionaryEntry* probe = bucket(index); | |
365 probe != NULL; | |
366 probe = probe->next()) { | |
367 klassOop k = probe->klass(); | |
368 f(k, probe->loader()); | |
369 } | |
370 } | |
371 } | |
372 | |
373 | |
374 void Dictionary::oops_do(OopClosure* f) { | |
375 for (int index = 0; index < table_size(); index++) { | |
376 for (DictionaryEntry* probe = bucket(index); | |
377 probe != NULL; | |
378 probe = probe->next()) { | |
379 f->do_oop((oop*)probe->klass_addr()); | |
380 if (probe->loader() != NULL) { | |
381 f->do_oop(probe->loader_addr()); | |
382 } | |
383 probe->protection_domain_set_oops_do(f); | |
384 } | |
385 } | |
386 } | |
387 | |
388 | |
389 void Dictionary::methods_do(void f(methodOop)) { | |
390 for (int index = 0; index < table_size(); index++) { | |
391 for (DictionaryEntry* probe = bucket(index); | |
392 probe != NULL; | |
393 probe = probe->next()) { | |
394 klassOop k = probe->klass(); | |
395 if (probe->loader() == instanceKlass::cast(k)->class_loader()) { | |
396 // only take klass is we have the entry with the defining class loader | |
397 instanceKlass::cast(k)->methods_do(f); | |
398 } | |
399 } | |
400 } | |
401 } | |
402 | |
403 | |
404 klassOop Dictionary::try_get_next_class() { | |
405 while (true) { | |
406 if (_current_class_entry != NULL) { | |
407 klassOop k = _current_class_entry->klass(); | |
408 _current_class_entry = _current_class_entry->next(); | |
409 return k; | |
410 } | |
411 _current_class_index = (_current_class_index + 1) % table_size(); | |
412 _current_class_entry = bucket(_current_class_index); | |
413 } | |
414 // never reached | |
415 } | |
416 | |
417 | |
418 // Add a loaded class to the system dictionary. | |
419 // Readers of the SystemDictionary aren't always locked, so _buckets | |
420 // is volatile. The store of the next field in the constructor is | |
421 // also cast to volatile; we do this to ensure store order is maintained | |
422 // by the compilers. | |
423 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
424 void Dictionary::add_klass(Symbol* class_name, Handle class_loader, |
0 | 425 KlassHandle obj) { |
426 assert_locked_or_safepoint(SystemDictionary_lock); | |
427 assert(obj() != NULL, "adding NULL obj"); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
428 assert(Klass::cast(obj())->name() == class_name, "sanity check on name"); |
0 | 429 |
430 unsigned int hash = compute_hash(class_name, class_loader); | |
431 int index = hash_to_index(hash); | |
432 DictionaryEntry* entry = new_entry(hash, obj(), class_loader()); | |
433 add_entry(index, entry); | |
434 } | |
435 | |
436 | |
437 // This routine does not lock the system dictionary. | |
438 // | |
439 // Since readers don't hold a lock, we must make sure that system | |
440 // dictionary entries are only removed at a safepoint (when only one | |
441 // thread is running), and are added to in a safe way (all links must | |
442 // be updated in an MT-safe manner). | |
443 // | |
444 // Callers should be aware that an entry could be added just after | |
445 // _buckets[index] is read here, so the caller will not see the new entry. | |
446 DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
447 Symbol* class_name, |
0 | 448 Handle class_loader) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
449 oop loader = class_loader(); |
0 | 450 debug_only(_lookup_count++); |
451 for (DictionaryEntry* entry = bucket(index); | |
452 entry != NULL; | |
453 entry = entry->next()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
454 if (entry->hash() == hash && entry->equals(class_name, loader)) { |
0 | 455 return entry; |
456 } | |
457 debug_only(_lookup_length++); | |
458 } | |
459 return NULL; | |
460 } | |
461 | |
462 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
463 klassOop Dictionary::find(int index, unsigned int hash, Symbol* name, |
0 | 464 Handle loader, Handle protection_domain, TRAPS) { |
465 DictionaryEntry* entry = get_entry(index, hash, name, loader); | |
466 if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { | |
467 return entry->klass(); | |
468 } else { | |
469 return NULL; | |
470 } | |
471 } | |
472 | |
473 | |
474 klassOop Dictionary::find_class(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
475 Symbol* name, Handle loader) { |
0 | 476 assert_locked_or_safepoint(SystemDictionary_lock); |
477 assert (index == index_for(name, loader), "incorrect index?"); | |
478 | |
479 DictionaryEntry* entry = get_entry(index, hash, name, loader); | |
480 return (entry != NULL) ? entry->klass() : (klassOop)NULL; | |
481 } | |
482 | |
483 | |
484 // Variant of find_class for shared classes. No locking required, as | |
485 // that table is static. | |
486 | |
487 klassOop Dictionary::find_shared_class(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
488 Symbol* name) { |
0 | 489 assert (index == index_for(name, Handle()), "incorrect index?"); |
490 | |
491 DictionaryEntry* entry = get_entry(index, hash, name, Handle()); | |
492 return (entry != NULL) ? entry->klass() : (klassOop)NULL; | |
493 } | |
494 | |
495 | |
496 void Dictionary::add_protection_domain(int index, unsigned int hash, | |
497 instanceKlassHandle klass, | |
498 Handle loader, Handle protection_domain, | |
499 TRAPS) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
500 Symbol* klass_name = klass->name(); |
0 | 501 DictionaryEntry* entry = get_entry(index, hash, klass_name, loader); |
502 | |
503 assert(entry != NULL,"entry must be present, we just created it"); | |
504 assert(protection_domain() != NULL, | |
505 "real protection domain should be present"); | |
506 | |
507 entry->add_protection_domain(protection_domain()); | |
508 | |
509 assert(entry->contains_protection_domain(protection_domain()), | |
510 "now protection domain should be present"); | |
511 } | |
512 | |
513 | |
514 bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
515 Symbol* name, |
0 | 516 Handle loader, |
517 Handle protection_domain) { | |
518 DictionaryEntry* entry = get_entry(index, hash, name, loader); | |
519 return entry->is_valid_protection_domain(protection_domain); | |
520 } | |
521 | |
522 | |
523 void Dictionary::reorder_dictionary() { | |
524 | |
525 // Copy all the dictionary entries into a single master list. | |
526 | |
527 DictionaryEntry* master_list = NULL; | |
528 for (int i = 0; i < table_size(); ++i) { | |
529 DictionaryEntry* p = bucket(i); | |
530 while (p != NULL) { | |
531 DictionaryEntry* tmp; | |
532 tmp = p->next(); | |
533 p->set_next(master_list); | |
534 master_list = p; | |
535 p = tmp; | |
536 } | |
537 set_entry(i, NULL); | |
538 } | |
539 | |
540 // Add the dictionary entries back to the list in the correct buckets. | |
541 Thread *thread = Thread::current(); | |
542 | |
543 while (master_list != NULL) { | |
544 DictionaryEntry* p = master_list; | |
545 master_list = master_list->next(); | |
546 p->set_next(NULL); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
547 Symbol* class_name = instanceKlass::cast((klassOop)(p->klass()))->name(); |
0 | 548 unsigned int hash = compute_hash(class_name, Handle(thread, p->loader())); |
549 int index = hash_to_index(hash); | |
550 p->set_hash(hash); | |
551 p->set_next(bucket(index)); | |
552 set_entry(index, p); | |
553 } | |
554 } | |
555 | |
710 | 556 SymbolPropertyTable::SymbolPropertyTable(int table_size) |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
557 : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry)) |
710 | 558 { |
559 } | |
560 SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, | |
561 int number_of_entries) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
562 : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) |
710 | 563 { |
564 } | |
565 | |
566 | |
567 SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
568 Symbol* sym, |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
710
diff
changeset
|
569 intptr_t sym_mode) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
710
diff
changeset
|
570 assert(index == index_for(sym, sym_mode), "incorrect index?"); |
710 | 571 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
572 if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) { |
710 | 573 return p; |
574 } | |
575 } | |
576 return NULL; | |
577 } | |
578 | |
579 | |
580 SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
581 Symbol* sym, intptr_t sym_mode) { |
710 | 582 assert_locked_or_safepoint(SystemDictionary_lock); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
710
diff
changeset
|
583 assert(index == index_for(sym, sym_mode), "incorrect index?"); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
710
diff
changeset
|
584 assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); |
710 | 585 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
586 SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
587 Hashtable<Symbol*>::add_entry(index, p); |
710 | 588 return p; |
589 } | |
590 | |
591 | |
592 void SymbolPropertyTable::oops_do(OopClosure* f) { | |
593 for (int index = 0; index < table_size(); index++) { | |
594 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { | |
595 if (p->property_oop() != NULL) { | |
596 f->do_oop(p->property_oop_addr()); | |
597 } | |
598 } | |
599 } | |
600 } | |
601 | |
602 void SymbolPropertyTable::methods_do(void f(methodOop)) { | |
603 for (int index = 0; index < table_size(); index++) { | |
604 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { | |
605 oop prop = p->property_oop(); | |
606 if (prop != NULL && prop->is_method()) { | |
607 f((methodOop)prop); | |
608 } | |
609 } | |
610 } | |
611 } | |
612 | |
0 | 613 |
614 // ---------------------------------------------------------------------------- | |
615 #ifndef PRODUCT | |
616 | |
617 void Dictionary::print() { | |
618 ResourceMark rm; | |
619 HandleMark hm; | |
620 | |
621 tty->print_cr("Java system dictionary (classes=%d)", number_of_entries()); | |
622 tty->print_cr("^ indicates that initiating loader is different from " | |
623 "defining loader"); | |
624 | |
625 for (int index = 0; index < table_size(); index++) { | |
626 for (DictionaryEntry* probe = bucket(index); | |
627 probe != NULL; | |
628 probe = probe->next()) { | |
629 if (Verbose) tty->print("%4d: ", index); | |
630 klassOop e = probe->klass(); | |
631 oop class_loader = probe->loader(); | |
632 bool is_defining_class = | |
633 (class_loader == instanceKlass::cast(e)->class_loader()); | |
634 tty->print("%s%s", is_defining_class ? " " : "^", | |
635 Klass::cast(e)->external_name()); | |
636 if (class_loader != NULL) { | |
637 tty->print(", loader "); | |
638 class_loader->print_value(); | |
639 } | |
640 tty->cr(); | |
641 } | |
642 } | |
643 } | |
644 | |
645 #endif | |
646 | |
647 void Dictionary::verify() { | |
648 guarantee(number_of_entries() >= 0, "Verify of system dictionary failed"); | |
649 int element_count = 0; | |
650 for (int index = 0; index < table_size(); index++) { | |
651 for (DictionaryEntry* probe = bucket(index); | |
652 probe != NULL; | |
653 probe = probe->next()) { | |
654 klassOop e = probe->klass(); | |
655 oop class_loader = probe->loader(); | |
656 guarantee(Klass::cast(e)->oop_is_instance(), | |
657 "Verify of system dictionary failed"); | |
658 // class loader must be present; a null class loader is the | |
659 // boostrap loader | |
660 guarantee(class_loader == NULL || class_loader->is_instance(), | |
661 "checking type of class_loader"); | |
662 e->verify(); | |
663 probe->verify_protection_domain_set(); | |
664 element_count++; | |
665 } | |
666 } | |
667 guarantee(number_of_entries() == element_count, | |
668 "Verify of system dictionary failed"); | |
669 debug_only(verify_lookup_length((double)number_of_entries() / table_size())); | |
670 } |