src/share/vm/classfile/loaderConstraints.cpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4304
90273fc0a981
parent 0
f90c822e73f8
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "classfile/classLoaderData.inline.hpp"
aoqi@0 27 #include "classfile/loaderConstraints.hpp"
aoqi@0 28 #include "memory/resourceArea.hpp"
aoqi@0 29 #include "oops/oop.inline.hpp"
aoqi@0 30 #include "runtime/handles.inline.hpp"
aoqi@0 31 #include "runtime/safepoint.hpp"
aoqi@0 32 #include "utilities/hashtable.inline.hpp"
aoqi@0 33
aoqi@0 34 void LoaderConstraintEntry::set_loader(int i, oop p) {
aoqi@0 35 set_loader_data(i, ClassLoaderData::class_loader_data(p));
aoqi@0 36 }
aoqi@0 37
aoqi@0 38 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
aoqi@0 39 : Hashtable<Klass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
aoqi@0 40
aoqi@0 41
aoqi@0 42 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
aoqi@0 43 unsigned int hash, Symbol* name,
aoqi@0 44 Klass* klass, int num_loaders,
aoqi@0 45 int max_loaders) {
aoqi@0 46 LoaderConstraintEntry* entry;
aoqi@0 47 entry = (LoaderConstraintEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass);
aoqi@0 48 entry->set_name(name);
aoqi@0 49 entry->set_num_loaders(num_loaders);
aoqi@0 50 entry->set_max_loaders(max_loaders);
aoqi@0 51 return entry;
aoqi@0 52 }
aoqi@0 53
aoqi@0 54 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
aoqi@0 55 // decrement name refcount before freeing
aoqi@0 56 entry->name()->decrement_refcount();
aoqi@0 57 Hashtable<Klass*, mtClass>::free_entry(entry);
aoqi@0 58 }
aoqi@0 59
aoqi@0 60 // Enhanced Class Redefinition support
aoqi@0 61 void LoaderConstraintTable::classes_do(KlassClosure* f) {
aoqi@0 62 for (int index = 0; index < table_size(); index++) {
aoqi@0 63 for (LoaderConstraintEntry* probe = bucket(index);
aoqi@0 64 probe != NULL;
aoqi@0 65 probe = probe->next()) {
aoqi@0 66 if (probe->klass() != NULL) {
aoqi@0 67 f->do_klass(probe->klass());
aoqi@0 68 }
aoqi@0 69 }
aoqi@0 70 }
aoqi@0 71 }
aoqi@0 72
aoqi@0 73 // The loaderConstraintTable must always be accessed with the
aoqi@0 74 // SystemDictionary lock held. This is true even for readers as
aoqi@0 75 // entries in the table could be being dynamically resized.
aoqi@0 76
aoqi@0 77 LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
aoqi@0 78 Symbol* name, Handle loader) {
aoqi@0 79
aoqi@0 80 unsigned int hash = compute_hash(name);
aoqi@0 81 int index = hash_to_index(hash);
aoqi@0 82 LoaderConstraintEntry** pp = bucket_addr(index);
aoqi@0 83 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
aoqi@0 84
aoqi@0 85 while (*pp) {
aoqi@0 86 LoaderConstraintEntry* p = *pp;
aoqi@0 87 if (p->hash() == hash) {
aoqi@0 88 if (p->name() == name) {
aoqi@0 89 for (int i = p->num_loaders() - 1; i >= 0; i--) {
aoqi@0 90 if (p->loader_data(i) == loader_data) {
aoqi@0 91 return pp;
aoqi@0 92 }
aoqi@0 93 }
aoqi@0 94 }
aoqi@0 95 }
aoqi@0 96 pp = p->next_addr();
aoqi@0 97 }
aoqi@0 98 return pp;
aoqi@0 99 }
aoqi@0 100
aoqi@0 101
aoqi@0 102 void LoaderConstraintTable::purge_loader_constraints() {
aoqi@0 103 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
aoqi@0 104 // Remove unloaded entries from constraint table
aoqi@0 105 for (int index = 0; index < table_size(); index++) {
aoqi@0 106 LoaderConstraintEntry** p = bucket_addr(index);
aoqi@0 107 while(*p) {
aoqi@0 108 LoaderConstraintEntry* probe = *p;
aoqi@0 109 Klass* klass = probe->klass();
aoqi@0 110 // Remove klass that is no longer alive
aoqi@0 111 if (klass != NULL &&
aoqi@0 112 klass->class_loader_data()->is_unloading()) {
aoqi@0 113 probe->set_klass(NULL);
aoqi@0 114 if (TraceLoaderConstraints) {
aoqi@0 115 ResourceMark rm;
aoqi@0 116 tty->print_cr("[Purging class object from constraint for name %s,"
aoqi@0 117 " loader list:",
aoqi@0 118 probe->name()->as_C_string());
aoqi@0 119 for (int i = 0; i < probe->num_loaders(); i++) {
aoqi@0 120 tty->print_cr("[ [%d]: %s", i,
aoqi@0 121 probe->loader_data(i)->loader_name());
aoqi@0 122 }
aoqi@0 123 }
aoqi@0 124 }
aoqi@0 125 // Remove entries no longer alive from loader array
aoqi@0 126 int n = 0;
aoqi@0 127 while (n < probe->num_loaders()) {
aoqi@0 128 if (probe->loader_data(n)->is_unloading()) {
aoqi@0 129 if (TraceLoaderConstraints) {
aoqi@0 130 ResourceMark rm;
aoqi@0 131 tty->print_cr("[Purging loader %s from constraint for name %s",
aoqi@0 132 probe->loader_data(n)->loader_name(),
aoqi@0 133 probe->name()->as_C_string()
aoqi@0 134 );
aoqi@0 135 }
aoqi@0 136
aoqi@0 137 // Compact array
aoqi@0 138 int num = probe->num_loaders() - 1;
aoqi@0 139 probe->set_num_loaders(num);
aoqi@0 140 probe->set_loader_data(n, probe->loader_data(num));
aoqi@0 141 probe->set_loader_data(num, NULL);
aoqi@0 142
aoqi@0 143 if (TraceLoaderConstraints) {
aoqi@0 144 ResourceMark rm;
aoqi@0 145 tty->print_cr("[New loader list:");
aoqi@0 146 for (int i = 0; i < probe->num_loaders(); i++) {
aoqi@0 147 tty->print_cr("[ [%d]: %s", i,
aoqi@0 148 probe->loader_data(i)->loader_name());
aoqi@0 149 }
aoqi@0 150 }
aoqi@0 151
aoqi@0 152 continue; // current element replaced, so restart without
aoqi@0 153 // incrementing n
aoqi@0 154 }
aoqi@0 155 n++;
aoqi@0 156 }
aoqi@0 157 // Check whether entry should be purged
aoqi@0 158 if (probe->num_loaders() < 2) {
aoqi@0 159 if (TraceLoaderConstraints) {
aoqi@0 160 ResourceMark rm;
aoqi@0 161 tty->print("[Purging complete constraint for name %s\n",
aoqi@0 162 probe->name()->as_C_string());
aoqi@0 163 }
aoqi@0 164
aoqi@0 165 // Purge entry
aoqi@0 166 *p = probe->next();
aoqi@0 167 FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass);
aoqi@0 168 free_entry(probe);
aoqi@0 169 } else {
aoqi@0 170 #ifdef ASSERT
aoqi@0 171 if (probe->klass() != NULL) {
aoqi@0 172 ClassLoaderData* loader_data =
aoqi@0 173 probe->klass()->class_loader_data();
aoqi@0 174 assert(!loader_data->is_unloading(), "klass should be live");
aoqi@0 175 }
aoqi@0 176 #endif
aoqi@0 177 // Go to next entry
aoqi@0 178 p = probe->next_addr();
aoqi@0 179 }
aoqi@0 180 }
aoqi@0 181 }
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 bool LoaderConstraintTable::add_entry(Symbol* class_name,
aoqi@0 185 Klass* klass1, Handle class_loader1,
aoqi@0 186 Klass* klass2, Handle class_loader2) {
aoqi@0 187 int failure_code = 0; // encode different reasons for failing
aoqi@0 188
aoqi@0 189 if (klass1 != NULL && klass2 != NULL && klass1 != klass2) {
aoqi@0 190 failure_code = 1;
aoqi@0 191 } else {
aoqi@0 192 Klass* klass = klass1 != NULL ? klass1 : klass2;
aoqi@0 193
aoqi@0 194 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name,
aoqi@0 195 class_loader1);
aoqi@0 196 if (*pp1 != NULL && (*pp1)->klass() != NULL) {
aoqi@0 197 if (klass != NULL) {
aoqi@0 198 if (klass != (*pp1)->klass()) {
aoqi@0 199 failure_code = 2;
aoqi@0 200 }
aoqi@0 201 } else {
aoqi@0 202 klass = (*pp1)->klass();
aoqi@0 203 }
aoqi@0 204 }
aoqi@0 205
aoqi@0 206 LoaderConstraintEntry** pp2 = find_loader_constraint(class_name,
aoqi@0 207 class_loader2);
aoqi@0 208 if (*pp2 != NULL && (*pp2)->klass() != NULL) {
aoqi@0 209 if (klass != NULL) {
aoqi@0 210 if (klass != (*pp2)->klass()) {
aoqi@0 211 failure_code = 3;
aoqi@0 212 }
aoqi@0 213 } else {
aoqi@0 214 klass = (*pp2)->klass();
aoqi@0 215 }
aoqi@0 216 }
aoqi@0 217
aoqi@0 218 if (failure_code == 0) {
aoqi@0 219 if (*pp1 == NULL && *pp2 == NULL) {
aoqi@0 220 unsigned int hash = compute_hash(class_name);
aoqi@0 221 int index = hash_to_index(hash);
aoqi@0 222 LoaderConstraintEntry* p;
aoqi@0 223 p = new_entry(hash, class_name, klass, 2, 2);
aoqi@0 224 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
aoqi@0 225 p->set_loader(0, class_loader1());
aoqi@0 226 p->set_loader(1, class_loader2());
aoqi@0 227 p->set_klass(klass);
aoqi@0 228 p->set_next(bucket(index));
aoqi@0 229 set_entry(index, p);
aoqi@0 230 if (TraceLoaderConstraints) {
aoqi@0 231 ResourceMark rm;
aoqi@0 232 tty->print("[Adding new constraint for name: %s, loader[0]: %s,"
aoqi@0 233 " loader[1]: %s ]\n",
aoqi@0 234 class_name->as_C_string(),
aoqi@0 235 SystemDictionary::loader_name(class_loader1()),
aoqi@0 236 SystemDictionary::loader_name(class_loader2())
aoqi@0 237 );
aoqi@0 238 }
aoqi@0 239 } else if (*pp1 == *pp2) {
aoqi@0 240 /* constraint already imposed */
aoqi@0 241 if ((*pp1)->klass() == NULL) {
aoqi@0 242 (*pp1)->set_klass(klass);
aoqi@0 243 if (TraceLoaderConstraints) {
aoqi@0 244 ResourceMark rm;
aoqi@0 245 tty->print("[Setting class object in existing constraint for"
aoqi@0 246 " name: %s and loader %s ]\n",
aoqi@0 247 class_name->as_C_string(),
aoqi@0 248 SystemDictionary::loader_name(class_loader1())
aoqi@0 249 );
aoqi@0 250 }
aoqi@0 251 } else {
aoqi@0 252 assert((*pp1)->klass() == klass, "loader constraints corrupted");
aoqi@0 253 }
aoqi@0 254 } else if (*pp1 == NULL) {
aoqi@0 255 extend_loader_constraint(*pp2, class_loader1, klass);
aoqi@0 256 } else if (*pp2 == NULL) {
aoqi@0 257 extend_loader_constraint(*pp1, class_loader2, klass);
aoqi@0 258 } else {
aoqi@0 259 merge_loader_constraints(pp1, pp2, klass);
aoqi@0 260 }
aoqi@0 261 }
aoqi@0 262 }
aoqi@0 263
aoqi@0 264 if (failure_code != 0 && TraceLoaderConstraints) {
aoqi@0 265 ResourceMark rm;
aoqi@0 266 const char* reason = "";
aoqi@0 267 switch(failure_code) {
aoqi@0 268 case 1: reason = "the class objects presented by loader[0] and loader[1]"
aoqi@0 269 " are different"; break;
aoqi@0 270 case 2: reason = "the class object presented by loader[0] does not match"
aoqi@0 271 " the stored class object in the constraint"; break;
aoqi@0 272 case 3: reason = "the class object presented by loader[1] does not match"
aoqi@0 273 " the stored class object in the constraint"; break;
aoqi@0 274 default: reason = "unknown reason code";
aoqi@0 275 }
aoqi@0 276 tty->print("[Failed to add constraint for name: %s, loader[0]: %s,"
aoqi@0 277 " loader[1]: %s, Reason: %s ]\n",
aoqi@0 278 class_name->as_C_string(),
aoqi@0 279 SystemDictionary::loader_name(class_loader1()),
aoqi@0 280 SystemDictionary::loader_name(class_loader2()),
aoqi@0 281 reason
aoqi@0 282 );
aoqi@0 283 }
aoqi@0 284
aoqi@0 285 return failure_code == 0;
aoqi@0 286 }
aoqi@0 287
aoqi@0 288
aoqi@0 289 // return true if the constraint was updated, false if the constraint is
aoqi@0 290 // violated
aoqi@0 291 bool LoaderConstraintTable::check_or_update(instanceKlassHandle k,
aoqi@0 292 Handle loader,
aoqi@0 293 Symbol* name) {
aoqi@0 294 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
aoqi@0 295 if (p && p->klass() != NULL && p->klass() != k()) {
aoqi@0 296 if (TraceLoaderConstraints) {
aoqi@0 297 ResourceMark rm;
aoqi@0 298 tty->print("[Constraint check failed for name %s, loader %s: "
aoqi@0 299 "the presented class object differs from that stored ]\n",
aoqi@0 300 name->as_C_string(),
aoqi@0 301 SystemDictionary::loader_name(loader()));
aoqi@0 302 }
aoqi@0 303 return false;
aoqi@0 304 } else {
aoqi@0 305 if (p && p->klass() == NULL) {
aoqi@0 306 p->set_klass(k());
aoqi@0 307 if (TraceLoaderConstraints) {
aoqi@0 308 ResourceMark rm;
aoqi@0 309 tty->print("[Updating constraint for name %s, loader %s, "
aoqi@0 310 "by setting class object ]\n",
aoqi@0 311 name->as_C_string(),
aoqi@0 312 SystemDictionary::loader_name(loader()));
aoqi@0 313 }
aoqi@0 314 }
aoqi@0 315 return true;
aoqi@0 316 }
aoqi@0 317 }
aoqi@0 318
aoqi@0 319 Klass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
aoqi@0 320 Handle loader) {
aoqi@0 321 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
aoqi@0 322 if (p != NULL && p->klass() != NULL) {
aoqi@0 323 if (p->klass()->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
aoqi@0 324 // Only return fully loaded classes. Classes found through the
aoqi@0 325 // constraints might still be in the process of loading.
aoqi@0 326 return NULL;
aoqi@0 327 }
aoqi@0 328 return p->klass();
aoqi@0 329 }
aoqi@0 330
aoqi@0 331 // No constraints, or else no klass loaded yet.
aoqi@0 332 return NULL;
aoqi@0 333 }
aoqi@0 334
aoqi@0 335 void LoaderConstraintTable::ensure_loader_constraint_capacity(
aoqi@0 336 LoaderConstraintEntry *p,
aoqi@0 337 int nfree) {
aoqi@0 338 if (p->max_loaders() - p->num_loaders() < nfree) {
aoqi@0 339 int n = nfree + p->num_loaders();
aoqi@0 340 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
aoqi@0 341 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
aoqi@0 342 p->set_max_loaders(n);
aoqi@0 343 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass);
aoqi@0 344 p->set_loaders(new_loaders);
aoqi@0 345 }
aoqi@0 346 }
aoqi@0 347
aoqi@0 348
aoqi@0 349 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
aoqi@0 350 Handle loader,
aoqi@0 351 Klass* klass) {
aoqi@0 352 ensure_loader_constraint_capacity(p, 1);
aoqi@0 353 int num = p->num_loaders();
aoqi@0 354 p->set_loader(num, loader());
aoqi@0 355 p->set_num_loaders(num + 1);
aoqi@0 356 if (TraceLoaderConstraints) {
aoqi@0 357 ResourceMark rm;
aoqi@0 358 tty->print("[Extending constraint for name %s by adding loader[%d]: %s %s",
aoqi@0 359 p->name()->as_C_string(),
aoqi@0 360 num,
aoqi@0 361 SystemDictionary::loader_name(loader()),
aoqi@0 362 (p->klass() == NULL ? " and setting class object ]\n" : " ]\n")
aoqi@0 363 );
aoqi@0 364 }
aoqi@0 365 if (p->klass() == NULL) {
aoqi@0 366 p->set_klass(klass);
aoqi@0 367 } else {
aoqi@0 368 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
aoqi@0 369 }
aoqi@0 370 }
aoqi@0 371
aoqi@0 372
aoqi@0 373 void LoaderConstraintTable::merge_loader_constraints(
aoqi@0 374 LoaderConstraintEntry** pp1,
aoqi@0 375 LoaderConstraintEntry** pp2,
aoqi@0 376 Klass* klass) {
aoqi@0 377 // make sure *pp1 has higher capacity
aoqi@0 378 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
aoqi@0 379 LoaderConstraintEntry** tmp = pp2;
aoqi@0 380 pp2 = pp1;
aoqi@0 381 pp1 = tmp;
aoqi@0 382 }
aoqi@0 383
aoqi@0 384 LoaderConstraintEntry* p1 = *pp1;
aoqi@0 385 LoaderConstraintEntry* p2 = *pp2;
aoqi@0 386
aoqi@0 387 ensure_loader_constraint_capacity(p1, p2->num_loaders());
aoqi@0 388
aoqi@0 389 for (int i = 0; i < p2->num_loaders(); i++) {
aoqi@0 390 int num = p1->num_loaders();
aoqi@0 391 p1->set_loader_data(num, p2->loader_data(i));
aoqi@0 392 p1->set_num_loaders(num + 1);
aoqi@0 393 }
aoqi@0 394
aoqi@0 395 if (TraceLoaderConstraints) {
aoqi@0 396 ResourceMark rm;
aoqi@0 397 tty->print_cr("[Merged constraints for name %s, new loader list:",
aoqi@0 398 p1->name()->as_C_string()
aoqi@0 399 );
aoqi@0 400
aoqi@0 401 for (int i = 0; i < p1->num_loaders(); i++) {
aoqi@0 402 tty->print_cr("[ [%d]: %s", i,
aoqi@0 403 p1->loader_data(i)->loader_name());
aoqi@0 404 }
aoqi@0 405 if (p1->klass() == NULL) {
aoqi@0 406 tty->print_cr("[... and setting class object]");
aoqi@0 407 }
aoqi@0 408 }
aoqi@0 409
aoqi@0 410 // p1->klass() will hold NULL if klass, p2->klass(), and old
aoqi@0 411 // p1->klass() are all NULL. In addition, all three must have
aoqi@0 412 // matching non-NULL values, otherwise either the constraints would
aoqi@0 413 // have been violated, or the constraints had been corrupted (and an
aoqi@0 414 // assertion would fail).
aoqi@0 415 if (p2->klass() != NULL) {
aoqi@0 416 assert(p2->klass() == klass, "constraints corrupted");
aoqi@0 417 }
aoqi@0 418 if (p1->klass() == NULL) {
aoqi@0 419 p1->set_klass(klass);
aoqi@0 420 } else {
aoqi@0 421 assert(p1->klass() == klass, "constraints corrupted");
aoqi@0 422 }
aoqi@0 423
aoqi@0 424 *pp2 = p2->next();
aoqi@0 425 FREE_C_HEAP_ARRAY(oop, p2->loaders(), mtClass);
aoqi@0 426 free_entry(p2);
aoqi@0 427 return;
aoqi@0 428 }
aoqi@0 429
aoqi@0 430
aoqi@0 431 void LoaderConstraintTable::verify(Dictionary* dictionary,
aoqi@0 432 PlaceholderTable* placeholders) {
aoqi@0 433 Thread *thread = Thread::current();
aoqi@0 434 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
aoqi@0 435 for (LoaderConstraintEntry* probe = bucket(cindex);
aoqi@0 436 probe != NULL;
aoqi@0 437 probe = probe->next()) {
aoqi@0 438 if (probe->klass() != NULL) {
aoqi@0 439 InstanceKlass* ik = InstanceKlass::cast(probe->klass());
aoqi@0 440 guarantee(ik->name() == probe->name(), "name should match");
aoqi@0 441 Symbol* name = ik->name();
aoqi@0 442 ClassLoaderData* loader_data = ik->class_loader_data();
aoqi@0 443 unsigned int d_hash = dictionary->compute_hash(name, loader_data);
aoqi@0 444 int d_index = dictionary->hash_to_index(d_hash);
aoqi@0 445 Klass* k = dictionary->find_class(d_index, d_hash, name, loader_data);
aoqi@0 446 if (k != NULL) {
aoqi@0 447 // We found the class in the system dictionary, so we should
aoqi@0 448 // make sure that the Klass* matches what we already have.
aoqi@0 449 guarantee(k == probe->klass(), "klass should be in dictionary");
aoqi@0 450 } else {
aoqi@0 451 // If we don't find the class in the system dictionary, it
aoqi@0 452 // has to be in the placeholders table.
aoqi@0 453 unsigned int p_hash = placeholders->compute_hash(name, loader_data);
aoqi@0 454 int p_index = placeholders->hash_to_index(p_hash);
aoqi@0 455 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash,
aoqi@0 456 name, loader_data);
aoqi@0 457
aoqi@0 458 // The InstanceKlass might not be on the entry, so the only
aoqi@0 459 // thing we can check here is whether we were successful in
aoqi@0 460 // finding the class in the placeholders table.
aoqi@0 461 guarantee(entry != NULL, "klass should be in the placeholders");
aoqi@0 462 }
aoqi@0 463 }
aoqi@0 464 for (int n = 0; n< probe->num_loaders(); n++) {
aoqi@0 465 assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing");
aoqi@0 466 }
aoqi@0 467 }
aoqi@0 468 }
aoqi@0 469 }
aoqi@0 470
aoqi@0 471 #ifndef PRODUCT
aoqi@0 472
aoqi@0 473 // Called with the system dictionary lock held
aoqi@0 474 void LoaderConstraintTable::print() {
aoqi@0 475 ResourceMark rm;
aoqi@0 476
aoqi@0 477 assert_locked_or_safepoint(SystemDictionary_lock);
aoqi@0 478 tty->print_cr("Java loader constraints (entries=%d)", _loader_constraint_size);
aoqi@0 479 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
aoqi@0 480 for (LoaderConstraintEntry* probe = bucket(cindex);
aoqi@0 481 probe != NULL;
aoqi@0 482 probe = probe->next()) {
aoqi@0 483 tty->print("%4d: ", cindex);
aoqi@0 484 probe->name()->print();
aoqi@0 485 tty->print(" , loaders:");
aoqi@0 486 for (int n = 0; n < probe->num_loaders(); n++) {
aoqi@0 487 probe->loader_data(n)->print_value();
aoqi@0 488 tty->print(", ");
aoqi@0 489 }
aoqi@0 490 tty->cr();
aoqi@0 491 }
aoqi@0 492 }
aoqi@0 493 }
aoqi@0 494 #endif

mercurial