Mercurial > hg > truffle
comparison src/share/vm/classfile/loaderConstraints.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | d2a62e0f25eb |
children | 070d523b96a7 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
21 * questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "classfile/classLoaderData.inline.hpp" | |
26 #include "classfile/loaderConstraints.hpp" | 27 #include "classfile/loaderConstraints.hpp" |
27 #include "memory/resourceArea.hpp" | 28 #include "memory/resourceArea.hpp" |
28 #include "oops/oop.inline.hpp" | 29 #include "oops/oop.inline.hpp" |
29 #include "runtime/handles.inline.hpp" | 30 #include "runtime/handles.inline.hpp" |
30 #include "runtime/safepoint.hpp" | 31 #include "runtime/safepoint.hpp" |
31 #include "utilities/hashtable.inline.hpp" | 32 #include "utilities/hashtable.inline.hpp" |
32 | 33 |
34 void LoaderConstraintEntry::set_loader(int i, oop p) { | |
35 set_loader_data(i, ClassLoaderData::class_loader_data(p)); | |
36 } | |
37 | |
33 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets) | 38 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets) |
34 : Hashtable<klassOop, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {}; | 39 : Hashtable<Klass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {}; |
35 | 40 |
36 | 41 |
37 LoaderConstraintEntry* LoaderConstraintTable::new_entry( | 42 LoaderConstraintEntry* LoaderConstraintTable::new_entry( |
38 unsigned int hash, Symbol* name, | 43 unsigned int hash, Symbol* name, |
39 klassOop klass, int num_loaders, | 44 Klass* klass, int num_loaders, |
40 int max_loaders) { | 45 int max_loaders) { |
41 LoaderConstraintEntry* entry; | 46 LoaderConstraintEntry* entry; |
42 entry = (LoaderConstraintEntry*)Hashtable<klassOop, mtClass>::new_entry(hash, klass); | 47 entry = (LoaderConstraintEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass); |
43 entry->set_name(name); | 48 entry->set_name(name); |
44 entry->set_num_loaders(num_loaders); | 49 entry->set_num_loaders(num_loaders); |
45 entry->set_max_loaders(max_loaders); | 50 entry->set_max_loaders(max_loaders); |
46 return entry; | 51 return entry; |
47 } | 52 } |
48 | 53 |
49 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) { | 54 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) { |
50 // decrement name refcount before freeing | 55 // decrement name refcount before freeing |
51 entry->name()->decrement_refcount(); | 56 entry->name()->decrement_refcount(); |
52 Hashtable<klassOop, mtClass>::free_entry(entry); | 57 Hashtable<Klass*, mtClass>::free_entry(entry); |
53 } | 58 } |
54 | 59 |
55 | 60 // Enhanced Class Redefinition support |
56 void LoaderConstraintTable::oops_do(OopClosure* f) { | 61 void LoaderConstraintTable::classes_do(KlassClosure* f) { |
57 for (int index = 0; index < table_size(); index++) { | 62 for (int index = 0; index < table_size(); index++) { |
58 for (LoaderConstraintEntry* probe = bucket(index); | 63 for (LoaderConstraintEntry* probe = bucket(index); |
59 probe != NULL; | 64 probe != NULL; |
60 probe = probe->next()) { | 65 probe = probe->next()) { |
61 if (probe->klass() != NULL) { | 66 if (probe->klass() != NULL) { |
62 f->do_oop((oop*)probe->klass_addr()); | 67 f->do_klass(probe->klass()); |
63 } | 68 } |
64 for (int n = 0; n < probe->num_loaders(); n++) { | 69 } |
65 if (probe->loader(n) != NULL) { | 70 } |
66 f->do_oop(probe->loader_addr(n)); | 71 } |
67 } | |
68 } | |
69 } | |
70 } | |
71 } | |
72 | |
73 | 72 |
74 // The loaderConstraintTable must always be accessed with the | 73 // The loaderConstraintTable must always be accessed with the |
75 // SystemDictionary lock held. This is true even for readers as | 74 // SystemDictionary lock held. This is true even for readers as |
76 // entries in the table could be being dynamically resized. | 75 // entries in the table could be being dynamically resized. |
77 | 76 |
79 Symbol* name, Handle loader) { | 78 Symbol* name, Handle loader) { |
80 | 79 |
81 unsigned int hash = compute_hash(name); | 80 unsigned int hash = compute_hash(name); |
82 int index = hash_to_index(hash); | 81 int index = hash_to_index(hash); |
83 LoaderConstraintEntry** pp = bucket_addr(index); | 82 LoaderConstraintEntry** pp = bucket_addr(index); |
83 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader()); | |
84 | |
84 while (*pp) { | 85 while (*pp) { |
85 LoaderConstraintEntry* p = *pp; | 86 LoaderConstraintEntry* p = *pp; |
86 if (p->hash() == hash) { | 87 if (p->hash() == hash) { |
87 if (p->name() == name) { | 88 if (p->name() == name) { |
88 for (int i = p->num_loaders() - 1; i >= 0; i--) { | 89 for (int i = p->num_loaders() - 1; i >= 0; i--) { |
89 if (p->loader(i) == loader()) { | 90 if (p->loader_data(i) == loader_data) { |
90 return pp; | 91 return pp; |
91 } | 92 } |
92 } | 93 } |
93 } | 94 } |
94 } | 95 } |
96 } | 97 } |
97 return pp; | 98 return pp; |
98 } | 99 } |
99 | 100 |
100 | 101 |
101 void LoaderConstraintTable::purge_loader_constraints(BoolObjectClosure* is_alive) { | 102 void LoaderConstraintTable::purge_loader_constraints() { |
102 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | 103 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
103 // Remove unloaded entries from constraint table | 104 // Remove unloaded entries from constraint table |
104 for (int index = 0; index < table_size(); index++) { | 105 for (int index = 0; index < table_size(); index++) { |
105 LoaderConstraintEntry** p = bucket_addr(index); | 106 LoaderConstraintEntry** p = bucket_addr(index); |
106 while(*p) { | 107 while(*p) { |
107 LoaderConstraintEntry* probe = *p; | 108 LoaderConstraintEntry* probe = *p; |
108 klassOop klass = probe->klass(); | 109 Klass* klass = probe->klass(); |
109 // Remove klass that is no longer alive | 110 // Remove klass that is no longer alive |
110 if (klass != NULL && !is_alive->do_object_b(klass)) { | 111 if (klass != NULL && |
112 klass->class_loader_data()->is_unloading()) { | |
111 probe->set_klass(NULL); | 113 probe->set_klass(NULL); |
112 if (TraceLoaderConstraints) { | 114 if (TraceLoaderConstraints) { |
113 ResourceMark rm; | 115 ResourceMark rm; |
114 tty->print_cr("[Purging class object from constraint for name %s," | 116 tty->print_cr("[Purging class object from constraint for name %s," |
115 " loader list:", | 117 " loader list:", |
116 probe->name()->as_C_string()); | 118 probe->name()->as_C_string()); |
117 for (int i = 0; i < probe->num_loaders(); i++) { | 119 for (int i = 0; i < probe->num_loaders(); i++) { |
118 tty->print_cr("[ [%d]: %s", i, | 120 tty->print_cr("[ [%d]: %s", i, |
119 SystemDictionary::loader_name(probe->loader(i))); | 121 SystemDictionary::loader_name(probe->loader_data(i))); |
120 } | 122 } |
121 } | 123 } |
122 } | 124 } |
123 // Remove entries no longer alive from loader array | 125 // Remove entries no longer alive from loader array |
124 int n = 0; | 126 int n = 0; |
125 while (n < probe->num_loaders()) { | 127 while (n < probe->num_loaders()) { |
126 if (probe->loader(n) != NULL) { | 128 if (probe->loader_data(n)->is_unloading()) { |
127 if (!is_alive->do_object_b(probe->loader(n))) { | |
128 if (TraceLoaderConstraints) { | 129 if (TraceLoaderConstraints) { |
129 ResourceMark rm; | 130 ResourceMark rm; |
130 tty->print_cr("[Purging loader %s from constraint for name %s", | 131 tty->print_cr("[Purging loader %s from constraint for name %s", |
131 SystemDictionary::loader_name(probe->loader(n)), | 132 SystemDictionary::loader_name(probe->loader_data(n)), |
132 probe->name()->as_C_string() | 133 probe->name()->as_C_string() |
133 ); | 134 ); |
134 } | 135 } |
135 | 136 |
136 // Compact array | 137 // Compact array |
137 int num = probe->num_loaders() - 1; | 138 int num = probe->num_loaders() - 1; |
138 probe->set_num_loaders(num); | 139 probe->set_num_loaders(num); |
139 probe->set_loader(n, probe->loader(num)); | 140 probe->set_loader_data(n, probe->loader_data(num)); |
140 probe->set_loader(num, NULL); | 141 probe->set_loader_data(num, NULL); |
141 | 142 |
142 if (TraceLoaderConstraints) { | 143 if (TraceLoaderConstraints) { |
143 ResourceMark rm; | 144 ResourceMark rm; |
144 tty->print_cr("[New loader list:"); | 145 tty->print_cr("[New loader list:"); |
145 for (int i = 0; i < probe->num_loaders(); i++) { | 146 for (int i = 0; i < probe->num_loaders(); i++) { |
146 tty->print_cr("[ [%d]: %s", i, | 147 tty->print_cr("[ [%d]: %s", i, |
147 SystemDictionary::loader_name(probe->loader(i))); | 148 SystemDictionary::loader_name(probe->loader_data(i))); |
148 } | 149 } |
149 } | 150 } |
150 | 151 |
151 continue; // current element replaced, so restart without | 152 continue; // current element replaced, so restart without |
152 // incrementing n | 153 // incrementing n |
153 } | 154 } |
154 } | |
155 n++; | 155 n++; |
156 } | 156 } |
157 // Check whether entry should be purged | 157 // Check whether entry should be purged |
158 if (probe->num_loaders() < 2) { | 158 if (probe->num_loaders() < 2) { |
159 if (TraceLoaderConstraints) { | 159 if (TraceLoaderConstraints) { |
167 FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass); | 167 FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass); |
168 free_entry(probe); | 168 free_entry(probe); |
169 } else { | 169 } else { |
170 #ifdef ASSERT | 170 #ifdef ASSERT |
171 if (probe->klass() != NULL) { | 171 if (probe->klass() != NULL) { |
172 assert(is_alive->do_object_b(probe->klass()), "klass should be live"); | 172 ClassLoaderData* loader_data = |
173 } | 173 probe->klass()->class_loader_data(); |
174 for (n = 0; n < probe->num_loaders(); n++) { | 174 assert(!loader_data->is_unloading(), "klass should be live"); |
175 if (probe->loader(n) != NULL) { | |
176 assert(is_alive->do_object_b(probe->loader(n)), "loader should be live"); | |
177 } | |
178 } | 175 } |
179 #endif | 176 #endif |
180 // Go to next entry | 177 // Go to next entry |
181 p = probe->next_addr(); | 178 p = probe->next_addr(); |
182 } | 179 } |
183 } | 180 } |
184 } | 181 } |
185 } | 182 } |
186 | 183 |
187 bool LoaderConstraintTable::add_entry(Symbol* class_name, | 184 bool LoaderConstraintTable::add_entry(Symbol* class_name, |
188 klassOop klass1, Handle class_loader1, | 185 Klass* klass1, Handle class_loader1, |
189 klassOop klass2, Handle class_loader2) { | 186 Klass* klass2, Handle class_loader2) { |
190 int failure_code = 0; // encode different reasons for failing | 187 int failure_code = 0; // encode different reasons for failing |
191 | 188 |
192 if (klass1 != NULL && klass2 != NULL && klass1 != klass2) { | 189 if (klass1 != NULL && klass2 != NULL && klass1 != klass2) { |
193 failure_code = 1; | 190 failure_code = 1; |
194 } else { | 191 } else { |
195 klassOop klass = klass1 != NULL ? klass1 : klass2; | 192 Klass* klass = klass1 != NULL ? klass1 : klass2; |
196 | 193 |
197 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, | 194 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, |
198 class_loader1); | 195 class_loader1); |
199 if (*pp1 != NULL && (*pp1)->klass() != NULL) { | 196 if (*pp1 != NULL && (*pp1)->klass() != NULL) { |
200 if (klass != NULL) { | 197 if (klass != NULL) { |
222 if (*pp1 == NULL && *pp2 == NULL) { | 219 if (*pp1 == NULL && *pp2 == NULL) { |
223 unsigned int hash = compute_hash(class_name); | 220 unsigned int hash = compute_hash(class_name); |
224 int index = hash_to_index(hash); | 221 int index = hash_to_index(hash); |
225 LoaderConstraintEntry* p; | 222 LoaderConstraintEntry* p; |
226 p = new_entry(hash, class_name, klass, 2, 2); | 223 p = new_entry(hash, class_name, klass, 2, 2); |
227 p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2, mtClass)); | 224 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass)); |
228 p->set_loader(0, class_loader1()); | 225 p->set_loader(0, class_loader1()); |
229 p->set_loader(1, class_loader2()); | 226 p->set_loader(1, class_loader2()); |
230 p->set_klass(klass); | 227 p->set_klass(klass); |
231 p->set_next(bucket(index)); | 228 p->set_next(bucket(index)); |
232 set_entry(index, p); | 229 set_entry(index, p); |
317 } | 314 } |
318 return true; | 315 return true; |
319 } | 316 } |
320 } | 317 } |
321 | 318 |
322 klassOop LoaderConstraintTable::find_constrained_klass(Symbol* name, | 319 Klass* LoaderConstraintTable::find_constrained_klass(Symbol* name, |
323 Handle loader) { | 320 Handle loader) { |
324 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); | 321 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); |
325 if (p != NULL && p->klass() != NULL) { | 322 if (p != NULL && p->klass() != NULL) { |
326 if (Klass::cast(p->klass())->oop_is_instance() && !instanceKlass::cast(p->klass())->is_loaded()) { | 323 if (Klass::cast(p->klass())->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) { |
327 // Only return fully loaded classes. Classes found through the | 324 // Only return fully loaded classes. Classes found through the |
328 // constraints might still be in the process of loading. | 325 // constraints might still be in the process of loading. |
329 return NULL; | 326 return NULL; |
330 } | 327 } |
331 return p->klass(); | 328 return p->klass(); |
338 void LoaderConstraintTable::ensure_loader_constraint_capacity( | 335 void LoaderConstraintTable::ensure_loader_constraint_capacity( |
339 LoaderConstraintEntry *p, | 336 LoaderConstraintEntry *p, |
340 int nfree) { | 337 int nfree) { |
341 if (p->max_loaders() - p->num_loaders() < nfree) { | 338 if (p->max_loaders() - p->num_loaders() < nfree) { |
342 int n = nfree + p->num_loaders(); | 339 int n = nfree + p->num_loaders(); |
343 oop* new_loaders = NEW_C_HEAP_ARRAY(oop, n, mtClass); | 340 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass); |
344 memcpy(new_loaders, p->loaders(), sizeof(oop) * p->num_loaders()); | 341 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders()); |
345 p->set_max_loaders(n); | 342 p->set_max_loaders(n); |
346 FREE_C_HEAP_ARRAY(oop, p->loaders(), mtClass); | 343 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass); |
347 p->set_loaders(new_loaders); | 344 p->set_loaders(new_loaders); |
348 } | 345 } |
349 } | 346 } |
350 | 347 |
351 | 348 |
352 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p, | 349 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p, |
353 Handle loader, | 350 Handle loader, |
354 klassOop klass) { | 351 Klass* klass) { |
355 ensure_loader_constraint_capacity(p, 1); | 352 ensure_loader_constraint_capacity(p, 1); |
356 int num = p->num_loaders(); | 353 int num = p->num_loaders(); |
357 p->set_loader(num, loader()); | 354 p->set_loader(num, loader()); |
358 p->set_num_loaders(num + 1); | 355 p->set_num_loaders(num + 1); |
359 if (TraceLoaderConstraints) { | 356 if (TraceLoaderConstraints) { |
374 | 371 |
375 | 372 |
376 void LoaderConstraintTable::merge_loader_constraints( | 373 void LoaderConstraintTable::merge_loader_constraints( |
377 LoaderConstraintEntry** pp1, | 374 LoaderConstraintEntry** pp1, |
378 LoaderConstraintEntry** pp2, | 375 LoaderConstraintEntry** pp2, |
379 klassOop klass) { | 376 Klass* klass) { |
380 // make sure *pp1 has higher capacity | 377 // make sure *pp1 has higher capacity |
381 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) { | 378 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) { |
382 LoaderConstraintEntry** tmp = pp2; | 379 LoaderConstraintEntry** tmp = pp2; |
383 pp2 = pp1; | 380 pp2 = pp1; |
384 pp1 = tmp; | 381 pp1 = tmp; |
389 | 386 |
390 ensure_loader_constraint_capacity(p1, p2->num_loaders()); | 387 ensure_loader_constraint_capacity(p1, p2->num_loaders()); |
391 | 388 |
392 for (int i = 0; i < p2->num_loaders(); i++) { | 389 for (int i = 0; i < p2->num_loaders(); i++) { |
393 int num = p1->num_loaders(); | 390 int num = p1->num_loaders(); |
394 p1->set_loader(num, p2->loader(i)); | 391 p1->set_loader_data(num, p2->loader_data(i)); |
395 p1->set_num_loaders(num + 1); | 392 p1->set_num_loaders(num + 1); |
396 } | 393 } |
397 | 394 |
398 if (TraceLoaderConstraints) { | 395 if (TraceLoaderConstraints) { |
399 ResourceMark rm; | 396 ResourceMark rm; |
401 p1->name()->as_C_string() | 398 p1->name()->as_C_string() |
402 ); | 399 ); |
403 | 400 |
404 for (int i = 0; i < p1->num_loaders(); i++) { | 401 for (int i = 0; i < p1->num_loaders(); i++) { |
405 tty->print_cr("[ [%d]: %s", i, | 402 tty->print_cr("[ [%d]: %s", i, |
406 SystemDictionary::loader_name(p1->loader(i))); | 403 SystemDictionary::loader_name(p1->loader_data(i))); |
407 } | 404 } |
408 if (p1->klass() == NULL) { | 405 if (p1->klass() == NULL) { |
409 tty->print_cr("[... and setting class object]"); | 406 tty->print_cr("[... and setting class object]"); |
410 } | 407 } |
411 } | 408 } |
437 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) { | 434 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) { |
438 for (LoaderConstraintEntry* probe = bucket(cindex); | 435 for (LoaderConstraintEntry* probe = bucket(cindex); |
439 probe != NULL; | 436 probe != NULL; |
440 probe = probe->next()) { | 437 probe = probe->next()) { |
441 if (probe->klass() != NULL) { | 438 if (probe->klass() != NULL) { |
442 instanceKlass* ik = instanceKlass::cast(probe->klass()); | 439 InstanceKlass* ik = InstanceKlass::cast(probe->klass()); |
443 guarantee(ik->name() == probe->name(), "name should match"); | 440 guarantee(ik->name() == probe->name(), "name should match"); |
444 Symbol* name = ik->name(); | 441 Symbol* name = ik->name(); |
445 Handle loader(thread, ik->class_loader()); | 442 ClassLoaderData* loader_data = ik->class_loader_data(); |
446 unsigned int d_hash = dictionary->compute_hash(name, loader); | 443 unsigned int d_hash = dictionary->compute_hash(name, loader_data); |
447 int d_index = dictionary->hash_to_index(d_hash); | 444 int d_index = dictionary->hash_to_index(d_hash); |
448 klassOop k = dictionary->find_class(d_index, d_hash, name, loader); | 445 Klass* k = dictionary->find_class(d_index, d_hash, name, loader_data); |
449 if (k != NULL) { | 446 if (k != NULL) { |
450 // We found the class in the system dictionary, so we should | 447 // We found the class in the system dictionary, so we should |
451 // make sure that the klassOop matches what we already have. | 448 // make sure that the Klass* matches what we already have. |
452 guarantee(k == probe->klass(), "klass should be in dictionary"); | 449 guarantee(k == probe->klass(), "klass should be in dictionary"); |
453 } else { | 450 } else { |
454 // If we don't find the class in the system dictionary, it | 451 // If we don't find the class in the system dictionary, it |
455 // has to be in the placeholders table. | 452 // has to be in the placeholders table. |
456 unsigned int p_hash = placeholders->compute_hash(name, loader); | 453 unsigned int p_hash = placeholders->compute_hash(name, loader_data); |
457 int p_index = placeholders->hash_to_index(p_hash); | 454 int p_index = placeholders->hash_to_index(p_hash); |
458 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash, | 455 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash, |
459 name, loader); | 456 name, loader_data); |
460 | 457 |
461 // The instanceKlass might not be on the entry, so the only | 458 // The InstanceKlass might not be on the entry, so the only |
462 // thing we can check here is whether we were successful in | 459 // thing we can check here is whether we were successful in |
463 // finding the class in the placeholders table. | 460 // finding the class in the placeholders table. |
464 guarantee(entry != NULL, "klass should be in the placeholders"); | 461 guarantee(entry != NULL, "klass should be in the placeholders"); |
465 } | 462 } |
466 } | 463 } |
467 for (int n = 0; n< probe->num_loaders(); n++) { | 464 for (int n = 0; n< probe->num_loaders(); n++) { |
468 guarantee(probe->loader(n)->is_oop_or_null(), "should be oop"); | 465 assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing"); |
469 } | 466 } |
470 } | 467 } |
471 } | 468 } |
472 } | 469 } |
473 | 470 |
485 probe = probe->next()) { | 482 probe = probe->next()) { |
486 tty->print("%4d: ", cindex); | 483 tty->print("%4d: ", cindex); |
487 probe->name()->print(); | 484 probe->name()->print(); |
488 tty->print(" , loaders:"); | 485 tty->print(" , loaders:"); |
489 for (int n = 0; n < probe->num_loaders(); n++) { | 486 for (int n = 0; n < probe->num_loaders(); n++) { |
490 probe->loader(n)->print_value(); | 487 probe->loader_data(n)->print_value(); |
491 tty->print(", "); | 488 tty->print(", "); |
492 } | 489 } |
493 tty->cr(); | 490 tty->cr(); |
494 } | 491 } |
495 } | 492 } |