annotate src/share/vm/classfile/dictionary.cpp @ 13639:644db104e2f0

8164207: Checking missing load-acquire in relation to _pd_set in dictionary.cpp Summary: Use load_acquire for accessing DictionaryEntry::_pd_set since it's accessed outside the SystemDictionary_lock Reviewed-by: zgu, twisti, dholmes, adinn
author coleenp
date Wed, 30 Aug 2017 19:18:22 -0400
parents 731370f39fcd
children 7df86c5f8b5d
rev   line source
duke@0 1 /*
coleenp@12500 2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
duke@0 7 * published by the Free Software Foundation.
duke@0 8 *
duke@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 13 * accompanied this code).
duke@0 14 *
duke@0 15 * You should have received a copy of the GNU General Public License version
duke@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 18 *
trims@1472 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1472 20 * or visit www.oracle.com if you need additional information or have any
trims@1472 21 * questions.
duke@0 22 *
duke@0 23 */
duke@0 24
stefank@1879 25 #include "precompiled.hpp"
goetz@9953 26 #include "classfile/classLoaderData.inline.hpp"
iklam@9545 27 #include "classfile/sharedClassUtil.hpp"
stefank@1879 28 #include "classfile/dictionary.hpp"
coleenp@12855 29 #include "classfile/protectionDomainCache.hpp"
stefank@1879 30 #include "classfile/systemDictionary.hpp"
iklam@9545 31 #include "classfile/systemDictionaryShared.hpp"
stuefe@13365 32 #include "logging/log.hpp"
stuefe@13365 33 #include "logging/logStream.hpp"
tschatzl@5427 34 #include "memory/iterator.hpp"
iklam@13442 35 #include "memory/metaspaceClosure.hpp"
jprovino@10762 36 #include "memory/resourceArea.hpp"
stefank@1879 37 #include "oops/oop.inline.hpp"
coleenp@13404 38 #include "runtime/atomic.hpp"
goetz@6402 39 #include "runtime/orderAccess.inline.hpp"
stefank@1879 40 #include "utilities/hashtable.inline.hpp"
duke@0 41
iklam@9545 42 size_t Dictionary::entry_size() {
iklam@9545 43 if (DumpSharedSpaces) {
iklam@9545 44 return SystemDictionaryShared::dictionary_entry_size();
iklam@9545 45 } else {
iklam@9545 46 return sizeof(DictionaryEntry);
iklam@9545 47 }
iklam@9545 48 }
duke@0 49
coleenp@13404 50 Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size)
coleenp@13404 51 : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) {
duke@0 52 };
duke@0 53
duke@0 54
coleenp@13404 55 Dictionary::Dictionary(ClassLoaderData* loader_data,
coleenp@13404 56 int table_size, HashtableBucket<mtClass>* t,
duke@0 57 int number_of_entries)
coleenp@13404 58 : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {
duke@0 59 };
duke@0 60
coleenp@13404 61 Dictionary::~Dictionary() {
coleenp@13404 62 DictionaryEntry* probe = NULL;
coleenp@13404 63 for (int index = 0; index < table_size(); index++) {
coleenp@13404 64 for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
coleenp@13404 65 probe = *p;
coleenp@13404 66 *p = probe->next();
coleenp@13404 67 free_entry(probe);
coleenp@13404 68 }
coleenp@13404 69 }
coleenp@13404 70 assert(number_of_entries() == 0, "should have removed all entries");
coleenp@13404 71 assert(new_entry_free_list() == NULL, "entry present on Dictionary's free list");
coleenp@13404 72 free_buckets();
tschatzl@5427 73 }
duke@0 74
coleenp@13404 75 DictionaryEntry* Dictionary::new_entry(unsigned int hash, InstanceKlass* klass) {
coleenp@13404 76 DictionaryEntry* entry = (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::allocate_new_entry(hash, klass);
duke@0 77 entry->set_pd_set(NULL);
coleenp@9266 78 assert(klass->is_instance_klass(), "Must be");
iklam@9545 79 if (DumpSharedSpaces) {
iklam@9545 80 SystemDictionaryShared::init_shared_dictionary_entry(klass, entry);
iklam@9545 81 }
duke@0 82 return entry;
duke@0 83 }
duke@0 84
duke@0 85
duke@0 86 void Dictionary::free_entry(DictionaryEntry* entry) {
duke@0 87 // avoid recursion when deleting linked list
coleenp@13639 88 // pd_set is accessed during a safepoint.
duke@0 89 while (entry->pd_set() != NULL) {
duke@0 90 ProtectionDomainEntry* to_delete = entry->pd_set();
duke@0 91 entry->set_pd_set(to_delete->next());
duke@0 92 delete to_delete;
duke@0 93 }
coleenp@13404 94 // Unlink from the Hashtable prior to freeing
coleenp@13404 95 unlink_entry(entry);
coleenp@13404 96 FREE_C_HEAP_ARRAY(char, entry);
duke@0 97 }
duke@0 98
duke@0 99
duke@0 100 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
duke@0 101 #ifdef ASSERT
coleenp@13404 102 if (protection_domain == instance_klass()->protection_domain()) {
duke@0 103 // Ensure this doesn't show up in the pd_set (invariant)
duke@0 104 bool in_pd_set = false;
coleenp@13639 105 for (ProtectionDomainEntry* current = pd_set_acquire();
duke@0 106 current != NULL;
duke@0 107 current = current->next()) {
duke@0 108 if (current->protection_domain() == protection_domain) {
duke@0 109 in_pd_set = true;
duke@0 110 break;
duke@0 111 }
duke@0 112 }
duke@0 113 if (in_pd_set) {
duke@0 114 assert(false, "A klass's protection domain should not show up "
duke@0 115 "in its sys. dict. PD set");
duke@0 116 }
duke@0 117 }
duke@0 118 #endif /* ASSERT */
duke@0 119
coleenp@13404 120 if (protection_domain == instance_klass()->protection_domain()) {
duke@0 121 // Succeeds trivially
duke@0 122 return true;
duke@0 123 }
duke@0 124
coleenp@13639 125 for (ProtectionDomainEntry* current = pd_set_acquire();
duke@0 126 current != NULL;
duke@0 127 current = current->next()) {
duke@0 128 if (current->protection_domain() == protection_domain) return true;
duke@0 129 }
duke@0 130 return false;
duke@0 131 }
duke@0 132
duke@0 133
coleenp@12503 134 void DictionaryEntry::add_protection_domain(Dictionary* dict, Handle protection_domain) {
duke@0 135 assert_locked_or_safepoint(SystemDictionary_lock);
coleenp@12503 136 if (!contains_protection_domain(protection_domain())) {
coleenp@13404 137 ProtectionDomainCacheEntry* entry = SystemDictionary::cache_get(protection_domain);
duke@0 138 ProtectionDomainEntry* new_head =
coleenp@13639 139 new ProtectionDomainEntry(entry, pd_set());
duke@0 140 // Warning: Preserve store ordering. The SystemDictionary is read
duke@0 141 // without locks. The new ProtectionDomainEntry must be
duke@0 142 // complete before other threads can be allowed to see it
duke@0 143 // via a store to _pd_set.
coleenp@13639 144 release_set_pd_set(new_head);
duke@0 145 }
stuefe@13365 146 LogTarget(Trace, protectiondomain) lt;
stuefe@13365 147 if (lt.is_enabled()) {
stuefe@13365 148 LogStream ls(lt);
stuefe@13365 149 print_count(&ls);
duke@0 150 }
duke@0 151 }
duke@0 152
duke@0 153
thartmann@6911 154 void Dictionary::do_unloading() {
jcoomes@1409 155 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
duke@0 156
coleenp@13404 157 // The NULL class loader doesn't initiate loading classes from other class loaders
coleenp@13404 158 if (loader_data() == ClassLoaderData::the_null_class_loader_data()) {
coleenp@13404 159 return;
coleenp@13404 160 }
coleenp@13404 161
coleenp@13404 162 // Remove unloaded entries and classes from this dictionary
duke@0 163 DictionaryEntry* probe = NULL;
thartmann@6911 164 for (int index = 0; index < table_size(); index++) {
duke@0 165 for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
duke@0 166 probe = *p;
coleenp@13404 167 InstanceKlass* ik = probe->instance_klass();
coleenp@13404 168 ClassLoaderData* k_def_class_loader_data = ik->class_loader_data();
duke@0 169
coleenp@13404 170 // If the klass that this loader initiated is dead,
coleenp@13404 171 // (determined by checking the defining class loader)
coleenp@13404 172 // remove this entry.
coleenp@13404 173 if (k_def_class_loader_data->is_unloading()) {
coleenp@13404 174 assert(k_def_class_loader_data != loader_data(),
coleenp@13404 175 "cannot have live defining loader and unreachable klass");
coleenp@13404 176 *p = probe->next();
coleenp@13404 177 free_entry(probe);
coleenp@13404 178 continue;
duke@0 179 }
duke@0 180 p = probe->next_addr();
duke@0 181 }
duke@0 182 }
duke@0 183 }
duke@0 184
iklam@6872 185 void Dictionary::remove_classes_in_error_state() {
iklam@6872 186 assert(DumpSharedSpaces, "supported only when dumping");
iklam@6872 187 DictionaryEntry* probe = NULL;
iklam@6872 188 for (int index = 0; index < table_size(); index++) {
iklam@6872 189 for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
iklam@6872 190 probe = *p;
coleenp@13404 191 InstanceKlass* ik = probe->instance_klass();
iklam@6872 192 if (ik->is_in_error_state()) { // purge this entry
iklam@6872 193 *p = probe->next();
iklam@6872 194 free_entry(probe);
iklam@6872 195 ResourceMark rm;
jiangli@7359 196 tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());
iklam@6872 197 continue;
iklam@6872 198 }
iklam@6872 199
iklam@6872 200 p = probe->next_addr();
iklam@6872 201 }
iklam@6872 202 }
iklam@6872 203 }
iklam@6872 204
coleenp@3602 205 // Just the classes from defining class loaders
coleenp@13404 206 void Dictionary::classes_do(void f(InstanceKlass*)) {
coleenp@3602 207 for (int index = 0; index < table_size(); index++) {
coleenp@3602 208 for (DictionaryEntry* probe = bucket(index);
coleenp@3602 209 probe != NULL;
coleenp@3602 210 probe = probe->next()) {
coleenp@13404 211 InstanceKlass* k = probe->instance_klass();
coleenp@13404 212 if (loader_data() == k->class_loader_data()) {
duke@0 213 f(k);
duke@0 214 }
duke@0 215 }
duke@0 216 }
duke@0 217 }
duke@0 218
duke@0 219 // Added for initialize_itable_for_klass to handle exceptions
duke@0 220 // Just the classes from defining class loaders
coleenp@13404 221 void Dictionary::classes_do(void f(InstanceKlass*, TRAPS), TRAPS) {
duke@0 222 for (int index = 0; index < table_size(); index++) {
duke@0 223 for (DictionaryEntry* probe = bucket(index);
duke@0 224 probe != NULL;
duke@0 225 probe = probe->next()) {
coleenp@13404 226 InstanceKlass* k = probe->instance_klass();
coleenp@13404 227 if (loader_data() == k->class_loader_data()) {
duke@0 228 f(k, CHECK);
duke@0 229 }
duke@0 230 }
duke@0 231 }
duke@0 232 }
duke@0 233
coleenp@13404 234 // All classes, and their class loaders, including initiating class loaders
coleenp@13404 235 void Dictionary::all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) {
duke@0 236 for (int index = 0; index < table_size(); index++) {
duke@0 237 for (DictionaryEntry* probe = bucket(index);
duke@0 238 probe != NULL;
duke@0 239 probe = probe->next()) {
coleenp@13404 240 InstanceKlass* k = probe->instance_klass();
coleenp@13404 241 f(k, loader_data());
duke@0 242 }
duke@0 243 }
duke@0 244 }
duke@0 245
iklam@13442 246 // Used to scan and relocate the classes during CDS archive dump.
iklam@13442 247 void Dictionary::classes_do(MetaspaceClosure* it) {
iklam@13442 248 assert(DumpSharedSpaces, "dump-time only");
iklam@13442 249 for (int index = 0; index < table_size(); index++) {
iklam@13442 250 for (DictionaryEntry* probe = bucket(index);
iklam@13442 251 probe != NULL;
iklam@13442 252 probe = probe->next()) {
iklam@13442 253 it->push(probe->klass_addr());
iklam@13442 254 ((SharedDictionaryEntry*)probe)->metaspace_pointers_do(it);
iklam@13442 255 }
iklam@13442 256 }
iklam@13442 257 }
iklam@13442 258
iklam@13442 259
duke@0 260
coleenp@13404 261 // Add a loaded class to the dictionary.
duke@0 262 // Readers of the SystemDictionary aren't always locked, so _buckets
duke@0 263 // is volatile. The store of the next field in the constructor is
duke@0 264 // also cast to volatile; we do this to ensure store order is maintained
duke@0 265 // by the compilers.
duke@0 266
coleenp@13404 267 void Dictionary::add_klass(int index, unsigned int hash, Symbol* class_name,
coleenp@12742 268 InstanceKlass* obj) {
duke@0 269 assert_locked_or_safepoint(SystemDictionary_lock);
coleenp@12742 270 assert(obj != NULL, "adding NULL obj");
coleenp@12742 271 assert(obj->name() == class_name, "sanity check on name");
duke@0 272
coleenp@13404 273 DictionaryEntry* entry = new_entry(hash, obj);
duke@0 274 add_entry(index, entry);
duke@0 275 }
duke@0 276
duke@0 277
coleenp@13404 278 // This routine does not lock the dictionary.
duke@0 279 //
duke@0 280 // Since readers don't hold a lock, we must make sure that system
duke@0 281 // dictionary entries are only removed at a safepoint (when only one
duke@0 282 // thread is running), and are added to in a safe way (all links must
duke@0 283 // be updated in an MT-safe manner).
duke@0 284 //
duke@0 285 // Callers should be aware that an entry could be added just after
duke@0 286 // _buckets[index] is read here, so the caller will not see the new entry.
duke@0 287 DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
coleenp@13404 288 Symbol* class_name) {
duke@0 289 for (DictionaryEntry* entry = bucket(index);
duke@0 290 entry != NULL;
duke@0 291 entry = entry->next()) {
coleenp@13404 292 if (entry->hash() == hash && entry->equals(class_name)) {
coleenp@13404 293 if (!DumpSharedSpaces || SystemDictionaryShared::is_builtin(entry)) {
coleenp@13404 294 return entry;
coleenp@13404 295 }
duke@0 296 }
duke@0 297 }
duke@0 298 return NULL;
duke@0 299 }
duke@0 300
duke@0 301
coleenp@12742 302 InstanceKlass* Dictionary::find(int index, unsigned int hash, Symbol* name,
coleenp@13404 303 Handle protection_domain) {
coleenp@13404 304 DictionaryEntry* entry = get_entry(index, hash, name);
duke@0 305 if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
coleenp@13404 306 return entry->instance_klass();
duke@0 307 } else {
duke@0 308 return NULL;
duke@0 309 }
duke@0 310 }
duke@0 311
duke@0 312
coleenp@12742 313 InstanceKlass* Dictionary::find_class(int index, unsigned int hash,
coleenp@13404 314 Symbol* name) {
duke@0 315 assert_locked_or_safepoint(SystemDictionary_lock);
coleenp@13404 316 assert (index == index_for(name), "incorrect index?");
duke@0 317
coleenp@13404 318 DictionaryEntry* entry = get_entry(index, hash, name);
coleenp@13404 319 return (entry != NULL) ? entry->instance_klass() : NULL;
duke@0 320 }
duke@0 321
duke@0 322
duke@0 323 // Variant of find_class for shared classes. No locking required, as
duke@0 324 // that table is static.
duke@0 325
coleenp@12742 326 InstanceKlass* Dictionary::find_shared_class(int index, unsigned int hash,
coleenp@12742 327 Symbol* name) {
coleenp@13404 328 assert (index == index_for(name), "incorrect index?");
duke@0 329
coleenp@13404 330 DictionaryEntry* entry = get_entry(index, hash, name);
coleenp@13404 331 return (entry != NULL) ? entry->instance_klass() : NULL;
duke@0 332 }
duke@0 333
duke@0 334
duke@0 335 void Dictionary::add_protection_domain(int index, unsigned int hash,
coleenp@12742 336 InstanceKlass* klass,
coleenp@13404 337 Handle protection_domain,
duke@0 338 TRAPS) {
coleenp@2062 339 Symbol* klass_name = klass->name();
coleenp@13404 340 DictionaryEntry* entry = get_entry(index, hash, klass_name);
duke@0 341
duke@0 342 assert(entry != NULL,"entry must be present, we just created it");
duke@0 343 assert(protection_domain() != NULL,
duke@0 344 "real protection domain should be present");
duke@0 345
coleenp@12503 346 entry->add_protection_domain(this, protection_domain);
duke@0 347
duke@0 348 assert(entry->contains_protection_domain(protection_domain()),
duke@0 349 "now protection domain should be present");
duke@0 350 }
duke@0 351
duke@0 352
duke@0 353 bool Dictionary::is_valid_protection_domain(int index, unsigned int hash,
coleenp@2062 354 Symbol* name,
duke@0 355 Handle protection_domain) {
coleenp@13404 356 DictionaryEntry* entry = get_entry(index, hash, name);
duke@0 357 return entry->is_valid_protection_domain(protection_domain);
duke@0 358 }
duke@0 359
duke@0 360
iklam@13442 361 void Dictionary::reorder_dictionary_for_sharing() {
duke@0 362
duke@0 363 // Copy all the dictionary entries into a single master list.
duke@0 364
duke@0 365 DictionaryEntry* master_list = NULL;
duke@0 366 for (int i = 0; i < table_size(); ++i) {
duke@0 367 DictionaryEntry* p = bucket(i);
duke@0 368 while (p != NULL) {
duke@0 369 DictionaryEntry* tmp;
duke@0 370 tmp = p->next();
duke@0 371 p->set_next(master_list);
duke@0 372 master_list = p;
duke@0 373 p = tmp;
duke@0 374 }
duke@0 375 set_entry(i, NULL);
duke@0 376 }
duke@0 377
duke@0 378 // Add the dictionary entries back to the list in the correct buckets.
duke@0 379 while (master_list != NULL) {
duke@0 380 DictionaryEntry* p = master_list;
duke@0 381 master_list = master_list->next();
duke@0 382 p->set_next(NULL);
coleenp@13404 383 Symbol* class_name = p->instance_klass()->name();
coleenp@3602 384 // Since the null class loader data isn't copied to the CDS archive,
coleenp@3602 385 // compute the hash with NULL for loader data.
coleenp@13404 386 unsigned int hash = compute_hash(class_name);
duke@0 387 int index = hash_to_index(hash);
duke@0 388 p->set_hash(hash);
duke@0 389 p->set_next(bucket(index));
duke@0 390 set_entry(index, p);
duke@0 391 }
duke@0 392 }
duke@0 393
goetz@9953 394
jrose@710 395 SymbolPropertyTable::SymbolPropertyTable(int table_size)
zgu@3465 396 : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))
jrose@710 397 {
jrose@710 398 }
zgu@3465 399 SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t,
jrose@710 400 int number_of_entries)
zgu@3465 401 : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
jrose@710 402 {
jrose@710 403 }
jrose@710 404
jrose@710 405
jrose@710 406 SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,
coleenp@2062 407 Symbol* sym,
jrose@1427 408 intptr_t sym_mode) {
jrose@1427 409 assert(index == index_for(sym, sym_mode), "incorrect index?");
jrose@710 410 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
coleenp@2062 411 if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) {
jrose@710 412 return p;
jrose@710 413 }
jrose@710 414 }
jrose@710 415 return NULL;
jrose@710 416 }
jrose@710 417
jrose@710 418
jrose@710 419 SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash,
coleenp@2062 420 Symbol* sym, intptr_t sym_mode) {
jrose@710 421 assert_locked_or_safepoint(SystemDictionary_lock);
jrose@1427 422 assert(index == index_for(sym, sym_mode), "incorrect index?");
jrose@1427 423 assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry");
jrose@710 424
coleenp@2062 425 SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);
zgu@3465 426 Hashtable<Symbol*, mtSymbol>::add_entry(index, p);
jrose@710 427 return p;
jrose@710 428 }
jrose@710 429
jrose@710 430 void SymbolPropertyTable::oops_do(OopClosure* f) {
jrose@710 431 for (int index = 0; index < table_size(); index++) {
jrose@710 432 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
coleenp@3602 433 if (p->method_type() != NULL) {
coleenp@3602 434 f->do_oop(p->method_type_addr());
jrose@710 435 }
jrose@710 436 }
jrose@710 437 }
jrose@710 438 }
jrose@710 439
coleenp@3602 440 void SymbolPropertyTable::methods_do(void f(Method*)) {
jrose@710 441 for (int index = 0; index < table_size(); index++) {
jrose@710 442 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
coleenp@3602 443 Method* prop = p->method();
coleenp@3602 444 if (prop != NULL) {
coleenp@3602 445 f((Method*)prop);
jrose@710 446 }
jrose@710 447 }
jrose@710 448 }
jrose@710 449 }
jrose@710 450
duke@0 451
duke@0 452 // ----------------------------------------------------------------------------
duke@0 453
coleenp@13438 454 void Dictionary::print_on(outputStream* st) const {
duke@0 455 ResourceMark rm;
duke@0 456
coleenp@13404 457 assert(loader_data() != NULL, "loader data should not be null");
coleenp@13438 458 st->print_cr("Java dictionary (table_size=%d, classes=%d)",
coleenp@13438 459 table_size(), number_of_entries());
coleenp@13438 460 st->print_cr("^ indicates that initiating loader is different from defining loader");
duke@0 461
duke@0 462 for (int index = 0; index < table_size(); index++) {
duke@0 463 for (DictionaryEntry* probe = bucket(index);
duke@0 464 probe != NULL;
duke@0 465 probe = probe->next()) {
coleenp@13404 466 Klass* e = probe->instance_klass();
duke@0 467 bool is_defining_class =
coleenp@13404 468 (loader_data() == e->class_loader_data());
coleenp@13438 469 st->print("%4d: %s%s, loader ", index, is_defining_class ? " " : "^", e->external_name());
coleenp@13438 470 ClassLoaderData* loader_data = e->class_loader_data();
coleenp@13438 471 if (loader_data == NULL) {
coleenp@13438 472 // Shared class not restored yet in shared dictionary
coleenp@13438 473 st->print("<shared, not restored>");
coleenp@13438 474 } else {
coleenp@13438 475 loader_data->print_value_on(st);
gziemski@11630 476 }
coleenp@13438 477 st->cr();
duke@0 478 }
duke@0 479 }
tschatzl@5427 480 tty->cr();
duke@0 481 }
duke@0 482
coleenp@13072 483 void DictionaryEntry::verify() {
coleenp@13404 484 Klass* e = instance_klass();
coleenp@13404 485 guarantee(e->is_instance_klass(),
coleenp@13404 486 "Verify of dictionary failed");
coleenp@13404 487 e->verify();
coleenp@13404 488 verify_protection_domain_set();
coleenp@13404 489 }
coleenp@13404 490
coleenp@13404 491 void Dictionary::verify() {
coleenp@13404 492 guarantee(number_of_entries() >= 0, "Verify of dictionary failed");
coleenp@13404 493
coleenp@13072 494 ClassLoaderData* cld = loader_data();
coleenp@13072 495 // class loader must be present; a null class loader is the
coleenp@13072 496 // boostrap loader
coleenp@13072 497 guarantee(cld != NULL || DumpSharedSpaces ||
coleenp@13072 498 cld->class_loader() == NULL ||
coleenp@13072 499 cld->class_loader()->is_instance(),
coleenp@13072 500 "checking type of class_loader");
coleenp@13404 501
coleenp@13404 502 ResourceMark rm;
coleenp@13404 503 stringStream tempst;
coleenp@13404 504 tempst.print("System Dictionary for %s", cld->loader_name());
coleenp@13404 505 verify_table<DictionaryEntry>(tempst.as_string());
gziemski@12264 506 }