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