1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/classfile/dictionary.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,722 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/dictionary.hpp" 1.30 +#include "classfile/systemDictionary.hpp" 1.31 +#include "memory/iterator.hpp" 1.32 +#include "oops/oop.inline.hpp" 1.33 +#include "prims/jvmtiRedefineClassesTrace.hpp" 1.34 +#include "utilities/hashtable.inline.hpp" 1.35 + 1.36 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.37 + 1.38 +DictionaryEntry* Dictionary::_current_class_entry = NULL; 1.39 +int Dictionary::_current_class_index = 0; 1.40 + 1.41 + 1.42 +Dictionary::Dictionary(int table_size) 1.43 + : TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry)) { 1.44 + _current_class_index = 0; 1.45 + _current_class_entry = NULL; 1.46 + _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize); 1.47 +}; 1.48 + 1.49 + 1.50 +Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t, 1.51 + int number_of_entries) 1.52 + : TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry), t, number_of_entries) { 1.53 + _current_class_index = 0; 1.54 + _current_class_entry = NULL; 1.55 + _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize); 1.56 +}; 1.57 + 1.58 +ProtectionDomainCacheEntry* Dictionary::cache_get(oop protection_domain) { 1.59 + return _pd_cache_table->get(protection_domain); 1.60 +} 1.61 + 1.62 +DictionaryEntry* Dictionary::new_entry(unsigned int hash, Klass* klass, 1.63 + ClassLoaderData* loader_data) { 1.64 + DictionaryEntry* entry = (DictionaryEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass); 1.65 + entry->set_loader_data(loader_data); 1.66 + entry->set_pd_set(NULL); 1.67 + assert(klass->oop_is_instance(), "Must be"); 1.68 + return entry; 1.69 +} 1.70 + 1.71 + 1.72 +void Dictionary::free_entry(DictionaryEntry* entry) { 1.73 + // avoid recursion when deleting linked list 1.74 + while (entry->pd_set() != NULL) { 1.75 + ProtectionDomainEntry* to_delete = entry->pd_set(); 1.76 + entry->set_pd_set(to_delete->next()); 1.77 + delete to_delete; 1.78 + } 1.79 + Hashtable<Klass*, mtClass>::free_entry(entry); 1.80 +} 1.81 + 1.82 + 1.83 +bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { 1.84 +#ifdef ASSERT 1.85 + if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) { 1.86 + // Ensure this doesn't show up in the pd_set (invariant) 1.87 + bool in_pd_set = false; 1.88 + for (ProtectionDomainEntry* current = _pd_set; 1.89 + current != NULL; 1.90 + current = current->next()) { 1.91 + if (current->protection_domain() == protection_domain) { 1.92 + in_pd_set = true; 1.93 + break; 1.94 + } 1.95 + } 1.96 + if (in_pd_set) { 1.97 + assert(false, "A klass's protection domain should not show up " 1.98 + "in its sys. dict. PD set"); 1.99 + } 1.100 + } 1.101 +#endif /* ASSERT */ 1.102 + 1.103 + if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) { 1.104 + // Succeeds trivially 1.105 + return true; 1.106 + } 1.107 + 1.108 + for (ProtectionDomainEntry* current = _pd_set; 1.109 + current != NULL; 1.110 + current = current->next()) { 1.111 + if (current->protection_domain() == protection_domain) return true; 1.112 + } 1.113 + return false; 1.114 +} 1.115 + 1.116 + 1.117 +void DictionaryEntry::add_protection_domain(Dictionary* dict, oop protection_domain) { 1.118 + assert_locked_or_safepoint(SystemDictionary_lock); 1.119 + if (!contains_protection_domain(protection_domain)) { 1.120 + ProtectionDomainCacheEntry* entry = dict->cache_get(protection_domain); 1.121 + ProtectionDomainEntry* new_head = 1.122 + new ProtectionDomainEntry(entry, _pd_set); 1.123 + // Warning: Preserve store ordering. The SystemDictionary is read 1.124 + // without locks. The new ProtectionDomainEntry must be 1.125 + // complete before other threads can be allowed to see it 1.126 + // via a store to _pd_set. 1.127 + OrderAccess::release_store_ptr(&_pd_set, new_head); 1.128 + } 1.129 + if (TraceProtectionDomainVerification && WizardMode) { 1.130 + print(); 1.131 + } 1.132 +} 1.133 + 1.134 + 1.135 +bool Dictionary::do_unloading() { 1.136 + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.137 + bool class_was_unloaded = false; 1.138 + int index = 0; // Defined here for portability! Do not move 1.139 + 1.140 + // Remove unloadable entries and classes from system dictionary 1.141 + // The placeholder array has been handled in always_strong_oops_do. 1.142 + DictionaryEntry* probe = NULL; 1.143 + for (index = 0; index < table_size(); index++) { 1.144 + for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) { 1.145 + probe = *p; 1.146 + Klass* e = probe->klass(); 1.147 + ClassLoaderData* loader_data = probe->loader_data(); 1.148 + 1.149 + InstanceKlass* ik = InstanceKlass::cast(e); 1.150 + 1.151 + // Non-unloadable classes were handled in always_strong_oops_do 1.152 + if (!is_strongly_reachable(loader_data, e)) { 1.153 + // Entry was not visited in phase1 (negated test from phase1) 1.154 + assert(!loader_data->is_the_null_class_loader_data(), "unloading entry with null class loader"); 1.155 + ClassLoaderData* k_def_class_loader_data = ik->class_loader_data(); 1.156 + 1.157 + // Do we need to delete this system dictionary entry? 1.158 + bool purge_entry = false; 1.159 + 1.160 + // Do we need to delete this system dictionary entry? 1.161 + if (loader_data->is_unloading()) { 1.162 + // If the loader is not live this entry should always be 1.163 + // removed (will never be looked up again). Note that this is 1.164 + // not the same as unloading the referred class. 1.165 + if (k_def_class_loader_data == loader_data) { 1.166 + // This is the defining entry, so the referred class is about 1.167 + // to be unloaded. 1.168 + class_was_unloaded = true; 1.169 + } 1.170 + // Also remove this system dictionary entry. 1.171 + purge_entry = true; 1.172 + 1.173 + } else { 1.174 + // The loader in this entry is alive. If the klass is dead, 1.175 + // (determined by checking the defining class loader) 1.176 + // the loader must be an initiating loader (rather than the 1.177 + // defining loader). Remove this entry. 1.178 + if (k_def_class_loader_data->is_unloading()) { 1.179 + // If we get here, the class_loader_data must not be the defining 1.180 + // loader, it must be an initiating one. 1.181 + assert(k_def_class_loader_data != loader_data, 1.182 + "cannot have live defining loader and unreachable klass"); 1.183 + // Loader is live, but class and its defining loader are dead. 1.184 + // Remove the entry. The class is going away. 1.185 + purge_entry = true; 1.186 + } 1.187 + } 1.188 + 1.189 + if (purge_entry) { 1.190 + *p = probe->next(); 1.191 + if (probe == _current_class_entry) { 1.192 + _current_class_entry = NULL; 1.193 + } 1.194 + free_entry(probe); 1.195 + continue; 1.196 + } 1.197 + } 1.198 + p = probe->next_addr(); 1.199 + } 1.200 + } 1.201 + return class_was_unloaded; 1.202 +} 1.203 + 1.204 + 1.205 +void Dictionary::always_strong_oops_do(OopClosure* blk) { 1.206 + // Follow all system classes and temporary placeholders in dictionary; only 1.207 + // protection domain oops contain references into the heap. In a first 1.208 + // pass over the system dictionary determine which need to be treated as 1.209 + // strongly reachable and mark them as such. 1.210 + for (int index = 0; index < table_size(); index++) { 1.211 + for (DictionaryEntry *probe = bucket(index); 1.212 + probe != NULL; 1.213 + probe = probe->next()) { 1.214 + Klass* e = probe->klass(); 1.215 + ClassLoaderData* loader_data = probe->loader_data(); 1.216 + if (is_strongly_reachable(loader_data, e)) { 1.217 + probe->set_strongly_reachable(); 1.218 + } 1.219 + } 1.220 + } 1.221 + // Then iterate over the protection domain cache to apply the closure on the 1.222 + // previously marked ones. 1.223 + _pd_cache_table->always_strong_oops_do(blk); 1.224 +} 1.225 + 1.226 + 1.227 +void Dictionary::always_strong_classes_do(KlassClosure* closure) { 1.228 + // Follow all system classes and temporary placeholders in dictionary 1.229 + for (int index = 0; index < table_size(); index++) { 1.230 + for (DictionaryEntry* probe = bucket(index); 1.231 + probe != NULL; 1.232 + probe = probe->next()) { 1.233 + Klass* e = probe->klass(); 1.234 + ClassLoaderData* loader_data = probe->loader_data(); 1.235 + if (is_strongly_reachable(loader_data, e)) { 1.236 + closure->do_klass(e); 1.237 + } 1.238 + } 1.239 + } 1.240 +} 1.241 + 1.242 + 1.243 +// Just the classes from defining class loaders 1.244 +void Dictionary::classes_do(void f(Klass*)) { 1.245 + for (int index = 0; index < table_size(); index++) { 1.246 + for (DictionaryEntry* probe = bucket(index); 1.247 + probe != NULL; 1.248 + probe = probe->next()) { 1.249 + Klass* k = probe->klass(); 1.250 + if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) { 1.251 + f(k); 1.252 + } 1.253 + } 1.254 + } 1.255 +} 1.256 + 1.257 +// Added for initialize_itable_for_klass to handle exceptions 1.258 +// Just the classes from defining class loaders 1.259 +void Dictionary::classes_do(void f(Klass*, TRAPS), TRAPS) { 1.260 + for (int index = 0; index < table_size(); index++) { 1.261 + for (DictionaryEntry* probe = bucket(index); 1.262 + probe != NULL; 1.263 + probe = probe->next()) { 1.264 + Klass* k = probe->klass(); 1.265 + if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) { 1.266 + f(k, CHECK); 1.267 + } 1.268 + } 1.269 + } 1.270 +} 1.271 + 1.272 +// All classes, and their class loaders 1.273 +// Don't iterate over placeholders 1.274 +void Dictionary::classes_do(void f(Klass*, ClassLoaderData*)) { 1.275 + for (int index = 0; index < table_size(); index++) { 1.276 + for (DictionaryEntry* probe = bucket(index); 1.277 + probe != NULL; 1.278 + probe = probe->next()) { 1.279 + Klass* k = probe->klass(); 1.280 + f(k, probe->loader_data()); 1.281 + } 1.282 + } 1.283 +} 1.284 + 1.285 +void Dictionary::oops_do(OopClosure* f) { 1.286 + // Only the protection domain oops contain references into the heap. Iterate 1.287 + // over all of them. 1.288 + _pd_cache_table->oops_do(f); 1.289 +} 1.290 + 1.291 +void Dictionary::methods_do(void f(Method*)) { 1.292 + for (int index = 0; index < table_size(); index++) { 1.293 + for (DictionaryEntry* probe = bucket(index); 1.294 + probe != NULL; 1.295 + probe = probe->next()) { 1.296 + Klass* k = probe->klass(); 1.297 + if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) { 1.298 + // only take klass is we have the entry with the defining class loader 1.299 + InstanceKlass::cast(k)->methods_do(f); 1.300 + } 1.301 + } 1.302 + } 1.303 +} 1.304 + 1.305 +void Dictionary::unlink(BoolObjectClosure* is_alive) { 1.306 + // Only the protection domain cache table may contain references to the heap 1.307 + // that need to be unlinked. 1.308 + _pd_cache_table->unlink(is_alive); 1.309 +} 1.310 + 1.311 +Klass* Dictionary::try_get_next_class() { 1.312 + while (true) { 1.313 + if (_current_class_entry != NULL) { 1.314 + Klass* k = _current_class_entry->klass(); 1.315 + _current_class_entry = _current_class_entry->next(); 1.316 + return k; 1.317 + } 1.318 + _current_class_index = (_current_class_index + 1) % table_size(); 1.319 + _current_class_entry = bucket(_current_class_index); 1.320 + } 1.321 + // never reached 1.322 +} 1.323 + 1.324 +// Add a loaded class to the system dictionary. 1.325 +// Readers of the SystemDictionary aren't always locked, so _buckets 1.326 +// is volatile. The store of the next field in the constructor is 1.327 +// also cast to volatile; we do this to ensure store order is maintained 1.328 +// by the compilers. 1.329 + 1.330 +void Dictionary::add_klass(Symbol* class_name, ClassLoaderData* loader_data, 1.331 + KlassHandle obj) { 1.332 + assert_locked_or_safepoint(SystemDictionary_lock); 1.333 + assert(obj() != NULL, "adding NULL obj"); 1.334 + assert(obj()->name() == class_name, "sanity check on name"); 1.335 + assert(loader_data != NULL, "Must be non-NULL"); 1.336 + 1.337 + unsigned int hash = compute_hash(class_name, loader_data); 1.338 + int index = hash_to_index(hash); 1.339 + DictionaryEntry* entry = new_entry(hash, obj(), loader_data); 1.340 + add_entry(index, entry); 1.341 +} 1.342 + 1.343 + 1.344 +// This routine does not lock the system dictionary. 1.345 +// 1.346 +// Since readers don't hold a lock, we must make sure that system 1.347 +// dictionary entries are only removed at a safepoint (when only one 1.348 +// thread is running), and are added to in a safe way (all links must 1.349 +// be updated in an MT-safe manner). 1.350 +// 1.351 +// Callers should be aware that an entry could be added just after 1.352 +// _buckets[index] is read here, so the caller will not see the new entry. 1.353 +DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, 1.354 + Symbol* class_name, 1.355 + ClassLoaderData* loader_data) { 1.356 + debug_only(_lookup_count++); 1.357 + for (DictionaryEntry* entry = bucket(index); 1.358 + entry != NULL; 1.359 + entry = entry->next()) { 1.360 + if (entry->hash() == hash && entry->equals(class_name, loader_data)) { 1.361 + return entry; 1.362 + } 1.363 + debug_only(_lookup_length++); 1.364 + } 1.365 + return NULL; 1.366 +} 1.367 + 1.368 + 1.369 +Klass* Dictionary::find(int index, unsigned int hash, Symbol* name, 1.370 + ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { 1.371 + DictionaryEntry* entry = get_entry(index, hash, name, loader_data); 1.372 + if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { 1.373 + return entry->klass(); 1.374 + } else { 1.375 + return NULL; 1.376 + } 1.377 +} 1.378 + 1.379 + 1.380 +Klass* Dictionary::find_class(int index, unsigned int hash, 1.381 + Symbol* name, ClassLoaderData* loader_data) { 1.382 + assert_locked_or_safepoint(SystemDictionary_lock); 1.383 + assert (index == index_for(name, loader_data), "incorrect index?"); 1.384 + 1.385 + DictionaryEntry* entry = get_entry(index, hash, name, loader_data); 1.386 + return (entry != NULL) ? entry->klass() : (Klass*)NULL; 1.387 +} 1.388 + 1.389 + 1.390 +// Variant of find_class for shared classes. No locking required, as 1.391 +// that table is static. 1.392 + 1.393 +Klass* Dictionary::find_shared_class(int index, unsigned int hash, 1.394 + Symbol* name) { 1.395 + assert (index == index_for(name, NULL), "incorrect index?"); 1.396 + 1.397 + DictionaryEntry* entry = get_entry(index, hash, name, NULL); 1.398 + return (entry != NULL) ? entry->klass() : (Klass*)NULL; 1.399 +} 1.400 + 1.401 + 1.402 +void Dictionary::add_protection_domain(int index, unsigned int hash, 1.403 + instanceKlassHandle klass, 1.404 + ClassLoaderData* loader_data, Handle protection_domain, 1.405 + TRAPS) { 1.406 + Symbol* klass_name = klass->name(); 1.407 + DictionaryEntry* entry = get_entry(index, hash, klass_name, loader_data); 1.408 + 1.409 + assert(entry != NULL,"entry must be present, we just created it"); 1.410 + assert(protection_domain() != NULL, 1.411 + "real protection domain should be present"); 1.412 + 1.413 + entry->add_protection_domain(this, protection_domain()); 1.414 + 1.415 + assert(entry->contains_protection_domain(protection_domain()), 1.416 + "now protection domain should be present"); 1.417 +} 1.418 + 1.419 + 1.420 +bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, 1.421 + Symbol* name, 1.422 + ClassLoaderData* loader_data, 1.423 + Handle protection_domain) { 1.424 + DictionaryEntry* entry = get_entry(index, hash, name, loader_data); 1.425 + return entry->is_valid_protection_domain(protection_domain); 1.426 +} 1.427 + 1.428 + 1.429 +void Dictionary::reorder_dictionary() { 1.430 + 1.431 + // Copy all the dictionary entries into a single master list. 1.432 + 1.433 + DictionaryEntry* master_list = NULL; 1.434 + for (int i = 0; i < table_size(); ++i) { 1.435 + DictionaryEntry* p = bucket(i); 1.436 + while (p != NULL) { 1.437 + DictionaryEntry* tmp; 1.438 + tmp = p->next(); 1.439 + p->set_next(master_list); 1.440 + master_list = p; 1.441 + p = tmp; 1.442 + } 1.443 + set_entry(i, NULL); 1.444 + } 1.445 + 1.446 + // Add the dictionary entries back to the list in the correct buckets. 1.447 + while (master_list != NULL) { 1.448 + DictionaryEntry* p = master_list; 1.449 + master_list = master_list->next(); 1.450 + p->set_next(NULL); 1.451 + Symbol* class_name = InstanceKlass::cast((Klass*)(p->klass()))->name(); 1.452 + // Since the null class loader data isn't copied to the CDS archive, 1.453 + // compute the hash with NULL for loader data. 1.454 + unsigned int hash = compute_hash(class_name, NULL); 1.455 + int index = hash_to_index(hash); 1.456 + p->set_hash(hash); 1.457 + p->set_loader_data(NULL); // loader_data isn't copied to CDS 1.458 + p->set_next(bucket(index)); 1.459 + set_entry(index, p); 1.460 + } 1.461 +} 1.462 + 1.463 +ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size) 1.464 + : Hashtable<oop, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry)) 1.465 +{ 1.466 +} 1.467 + 1.468 +void ProtectionDomainCacheTable::unlink(BoolObjectClosure* is_alive) { 1.469 + assert(SafepointSynchronize::is_at_safepoint(), "must be"); 1.470 + for (int i = 0; i < table_size(); ++i) { 1.471 + ProtectionDomainCacheEntry** p = bucket_addr(i); 1.472 + ProtectionDomainCacheEntry* entry = bucket(i); 1.473 + while (entry != NULL) { 1.474 + if (is_alive->do_object_b(entry->literal())) { 1.475 + p = entry->next_addr(); 1.476 + } else { 1.477 + *p = entry->next(); 1.478 + free_entry(entry); 1.479 + } 1.480 + entry = *p; 1.481 + } 1.482 + } 1.483 +} 1.484 + 1.485 +void ProtectionDomainCacheTable::oops_do(OopClosure* f) { 1.486 + for (int index = 0; index < table_size(); index++) { 1.487 + for (ProtectionDomainCacheEntry* probe = bucket(index); 1.488 + probe != NULL; 1.489 + probe = probe->next()) { 1.490 + probe->oops_do(f); 1.491 + } 1.492 + } 1.493 +} 1.494 + 1.495 +uint ProtectionDomainCacheTable::bucket_size() { 1.496 + return sizeof(ProtectionDomainCacheEntry); 1.497 +} 1.498 + 1.499 +#ifndef PRODUCT 1.500 +void ProtectionDomainCacheTable::print() { 1.501 + tty->print_cr("Protection domain cache table (table_size=%d, classes=%d)", 1.502 + table_size(), number_of_entries()); 1.503 + for (int index = 0; index < table_size(); index++) { 1.504 + for (ProtectionDomainCacheEntry* probe = bucket(index); 1.505 + probe != NULL; 1.506 + probe = probe->next()) { 1.507 + probe->print(); 1.508 + } 1.509 + } 1.510 +} 1.511 + 1.512 +void ProtectionDomainCacheEntry::print() { 1.513 + tty->print_cr("entry "PTR_FORMAT" value "PTR_FORMAT" strongly_reachable %d next "PTR_FORMAT, 1.514 + this, (void*)literal(), _strongly_reachable, next()); 1.515 +} 1.516 +#endif 1.517 + 1.518 +void ProtectionDomainCacheTable::verify() { 1.519 + int element_count = 0; 1.520 + for (int index = 0; index < table_size(); index++) { 1.521 + for (ProtectionDomainCacheEntry* probe = bucket(index); 1.522 + probe != NULL; 1.523 + probe = probe->next()) { 1.524 + probe->verify(); 1.525 + element_count++; 1.526 + } 1.527 + } 1.528 + guarantee(number_of_entries() == element_count, 1.529 + "Verify of protection domain cache table failed"); 1.530 + debug_only(verify_lookup_length((double)number_of_entries() / table_size())); 1.531 +} 1.532 + 1.533 +void ProtectionDomainCacheEntry::verify() { 1.534 + guarantee(literal()->is_oop(), "must be an oop"); 1.535 +} 1.536 + 1.537 +void ProtectionDomainCacheTable::always_strong_oops_do(OopClosure* f) { 1.538 + // the caller marked the protection domain cache entries that we need to apply 1.539 + // the closure on. Only process them. 1.540 + for (int index = 0; index < table_size(); index++) { 1.541 + for (ProtectionDomainCacheEntry* probe = bucket(index); 1.542 + probe != NULL; 1.543 + probe = probe->next()) { 1.544 + if (probe->is_strongly_reachable()) { 1.545 + probe->reset_strongly_reachable(); 1.546 + probe->oops_do(f); 1.547 + } 1.548 + } 1.549 + } 1.550 +} 1.551 + 1.552 +ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(oop protection_domain) { 1.553 + unsigned int hash = compute_hash(protection_domain); 1.554 + int index = hash_to_index(hash); 1.555 + 1.556 + ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain); 1.557 + if (entry == NULL) { 1.558 + entry = add_entry(index, hash, protection_domain); 1.559 + } 1.560 + return entry; 1.561 +} 1.562 + 1.563 +ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, oop protection_domain) { 1.564 + for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) { 1.565 + if (e->protection_domain() == protection_domain) { 1.566 + return e; 1.567 + } 1.568 + } 1.569 + 1.570 + return NULL; 1.571 +} 1.572 + 1.573 +ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, oop protection_domain) { 1.574 + assert_locked_or_safepoint(SystemDictionary_lock); 1.575 + assert(index == index_for(protection_domain), "incorrect index?"); 1.576 + assert(find_entry(index, protection_domain) == NULL, "no double entry"); 1.577 + 1.578 + ProtectionDomainCacheEntry* p = new_entry(hash, protection_domain); 1.579 + Hashtable<oop, mtClass>::add_entry(index, p); 1.580 + return p; 1.581 +} 1.582 + 1.583 +void ProtectionDomainCacheTable::free(ProtectionDomainCacheEntry* to_delete) { 1.584 + unsigned int hash = compute_hash(to_delete->protection_domain()); 1.585 + int index = hash_to_index(hash); 1.586 + 1.587 + ProtectionDomainCacheEntry** p = bucket_addr(index); 1.588 + ProtectionDomainCacheEntry* entry = bucket(index); 1.589 + while (true) { 1.590 + assert(entry != NULL, "sanity"); 1.591 + 1.592 + if (entry == to_delete) { 1.593 + *p = entry->next(); 1.594 + Hashtable<oop, mtClass>::free_entry(entry); 1.595 + break; 1.596 + } else { 1.597 + p = entry->next_addr(); 1.598 + entry = *p; 1.599 + } 1.600 + } 1.601 +} 1.602 + 1.603 +SymbolPropertyTable::SymbolPropertyTable(int table_size) 1.604 + : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry)) 1.605 +{ 1.606 +} 1.607 +SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, 1.608 + int number_of_entries) 1.609 + : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) 1.610 +{ 1.611 +} 1.612 + 1.613 + 1.614 +SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, 1.615 + Symbol* sym, 1.616 + intptr_t sym_mode) { 1.617 + assert(index == index_for(sym, sym_mode), "incorrect index?"); 1.618 + for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 1.619 + if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) { 1.620 + return p; 1.621 + } 1.622 + } 1.623 + return NULL; 1.624 +} 1.625 + 1.626 + 1.627 +SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, 1.628 + Symbol* sym, intptr_t sym_mode) { 1.629 + assert_locked_or_safepoint(SystemDictionary_lock); 1.630 + assert(index == index_for(sym, sym_mode), "incorrect index?"); 1.631 + assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); 1.632 + 1.633 + SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode); 1.634 + Hashtable<Symbol*, mtSymbol>::add_entry(index, p); 1.635 + return p; 1.636 +} 1.637 + 1.638 +void SymbolPropertyTable::oops_do(OopClosure* f) { 1.639 + for (int index = 0; index < table_size(); index++) { 1.640 + for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 1.641 + if (p->method_type() != NULL) { 1.642 + f->do_oop(p->method_type_addr()); 1.643 + } 1.644 + } 1.645 + } 1.646 +} 1.647 + 1.648 +void SymbolPropertyTable::methods_do(void f(Method*)) { 1.649 + for (int index = 0; index < table_size(); index++) { 1.650 + for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 1.651 + Method* prop = p->method(); 1.652 + if (prop != NULL) { 1.653 + f((Method*)prop); 1.654 + } 1.655 + } 1.656 + } 1.657 +} 1.658 + 1.659 + 1.660 +// ---------------------------------------------------------------------------- 1.661 +#ifndef PRODUCT 1.662 + 1.663 +void Dictionary::print() { 1.664 + ResourceMark rm; 1.665 + HandleMark hm; 1.666 + 1.667 + tty->print_cr("Java system dictionary (table_size=%d, classes=%d)", 1.668 + table_size(), number_of_entries()); 1.669 + tty->print_cr("^ indicates that initiating loader is different from " 1.670 + "defining loader"); 1.671 + 1.672 + for (int index = 0; index < table_size(); index++) { 1.673 + for (DictionaryEntry* probe = bucket(index); 1.674 + probe != NULL; 1.675 + probe = probe->next()) { 1.676 + if (Verbose) tty->print("%4d: ", index); 1.677 + Klass* e = probe->klass(); 1.678 + ClassLoaderData* loader_data = probe->loader_data(); 1.679 + bool is_defining_class = 1.680 + (loader_data == InstanceKlass::cast(e)->class_loader_data()); 1.681 + tty->print("%s%s", is_defining_class ? " " : "^", 1.682 + e->external_name()); 1.683 + 1.684 + tty->print(", loader "); 1.685 + loader_data->print_value(); 1.686 + tty->cr(); 1.687 + } 1.688 + } 1.689 + tty->cr(); 1.690 + _pd_cache_table->print(); 1.691 + tty->cr(); 1.692 +} 1.693 + 1.694 +#endif 1.695 + 1.696 +void Dictionary::verify() { 1.697 + guarantee(number_of_entries() >= 0, "Verify of system dictionary failed"); 1.698 + 1.699 + int element_count = 0; 1.700 + for (int index = 0; index < table_size(); index++) { 1.701 + for (DictionaryEntry* probe = bucket(index); 1.702 + probe != NULL; 1.703 + probe = probe->next()) { 1.704 + Klass* e = probe->klass(); 1.705 + ClassLoaderData* loader_data = probe->loader_data(); 1.706 + guarantee(e->oop_is_instance(), 1.707 + "Verify of system dictionary failed"); 1.708 + // class loader must be present; a null class loader is the 1.709 + // boostrap loader 1.710 + guarantee(loader_data != NULL || DumpSharedSpaces || 1.711 + loader_data->class_loader() == NULL || 1.712 + loader_data->class_loader()->is_instance(), 1.713 + "checking type of class_loader"); 1.714 + e->verify(); 1.715 + probe->verify_protection_domain_set(); 1.716 + element_count++; 1.717 + } 1.718 + } 1.719 + guarantee(number_of_entries() == element_count, 1.720 + "Verify of system dictionary failed"); 1.721 + debug_only(verify_lookup_length((double)number_of_entries() / table_size())); 1.722 + 1.723 + _pd_cache_table->verify(); 1.724 +} 1.725 +