184 } |
184 } |
185 |
185 |
186 // GC root of class loader data created. |
186 // GC root of class loader data created. |
187 ClassLoaderData* volatile ClassLoaderDataGraph::_head = NULL; |
187 ClassLoaderData* volatile ClassLoaderDataGraph::_head = NULL; |
188 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; |
188 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; |
189 ClassLoaderData* ClassLoaderDataGraph::_saved_unloading = NULL; |
189 |
190 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; |
|
191 |
|
192 bool ClassLoaderDataGraph::_should_purge = false; |
|
193 bool ClassLoaderDataGraph::_should_clean_deallocate_lists = false; |
190 bool ClassLoaderDataGraph::_should_clean_deallocate_lists = false; |
194 bool ClassLoaderDataGraph::_safepoint_cleanup_needed = false; |
191 bool ClassLoaderDataGraph::_safepoint_cleanup_needed = false; |
195 bool ClassLoaderDataGraph::_metaspace_oom = false; |
192 bool ClassLoaderDataGraph::_metaspace_oom = false; |
196 |
193 |
197 // Add a new class loader data node to the list. Assign the newly created |
194 // Add a new class loader data node to the list. Assign the newly created |
247 return loader_data; |
244 return loader_data; |
248 } |
245 } |
249 |
246 |
250 void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) { |
247 void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) { |
251 assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock); |
248 assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock); |
252 // Only walk the head until any clds not purged from prior unloading |
249 for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { |
253 // (CMS doesn't purge right away). |
|
254 for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) { |
|
255 assert(cld->is_unloading(), "invariant"); |
250 assert(cld->is_unloading(), "invariant"); |
256 cl->do_cld(cld); |
251 cl->do_cld(cld); |
257 } |
252 } |
258 } |
253 } |
259 |
254 |
379 } |
374 } |
380 } |
375 } |
381 |
376 |
382 void ClassLoaderDataGraph::modules_unloading_do(void f(ModuleEntry*)) { |
377 void ClassLoaderDataGraph::modules_unloading_do(void f(ModuleEntry*)) { |
383 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
378 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
384 // Only walk the head until any clds not purged from prior unloading |
379 for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { |
385 // (CMS doesn't purge right away). |
|
386 for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) { |
|
387 assert(cld->is_unloading(), "invariant"); |
380 assert(cld->is_unloading(), "invariant"); |
388 cld->modules_do(f); |
381 cld->modules_do(f); |
389 } |
382 } |
390 } |
383 } |
391 |
384 |
397 } |
390 } |
398 } |
391 } |
399 |
392 |
400 void ClassLoaderDataGraph::packages_unloading_do(void f(PackageEntry*)) { |
393 void ClassLoaderDataGraph::packages_unloading_do(void f(PackageEntry*)) { |
401 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
394 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
402 // Only walk the head until any clds not purged from prior unloading |
395 for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { |
403 // (CMS doesn't purge right away). |
|
404 for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) { |
|
405 assert(cld->is_unloading(), "invariant"); |
396 assert(cld->is_unloading(), "invariant"); |
406 cld->packages_do(f); |
397 cld->packages_do(f); |
407 } |
398 } |
408 } |
399 } |
409 |
400 |
422 } |
413 } |
423 |
414 |
424 |
415 |
425 void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) { |
416 void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) { |
426 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
417 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
427 // Only walk the head until any clds not purged from prior unloading |
418 for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { |
428 // (CMS doesn't purge right away). |
|
429 for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) { |
|
430 assert(cld->is_unloading(), "invariant"); |
419 assert(cld->is_unloading(), "invariant"); |
431 cld->classes_do(f); |
420 cld->classes_do(f); |
432 } |
421 } |
433 } |
422 } |
434 |
423 |
474 tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id()); |
463 tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id()); |
475 cld->dictionary()->print_table_statistics(st, tempst.as_string()); |
464 cld->dictionary()->print_table_statistics(st, tempst.as_string()); |
476 } |
465 } |
477 } |
466 } |
478 |
467 |
479 GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() { |
|
480 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
|
481 assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?"); |
|
482 |
|
483 GrowableArray<ClassLoaderData*>* array = new GrowableArray<ClassLoaderData*>(); |
|
484 |
|
485 // The CLDs in [_head, _saved_head] were all added during last call to remember_new_clds(true); |
|
486 ClassLoaderData* curr = _head; |
|
487 while (curr != _saved_head) { |
|
488 if (!curr->claimed(ClassLoaderData::_claim_strong)) { |
|
489 array->push(curr); |
|
490 LogTarget(Debug, class, loader, data) lt; |
|
491 if (lt.is_enabled()) { |
|
492 LogStream ls(lt); |
|
493 ls.print("found new CLD: "); |
|
494 curr->print_value_on(&ls); |
|
495 ls.cr(); |
|
496 } |
|
497 } |
|
498 |
|
499 curr = curr->_next; |
|
500 } |
|
501 |
|
502 return array; |
|
503 } |
|
504 |
|
505 #ifndef PRODUCT |
468 #ifndef PRODUCT |
506 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { |
469 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { |
507 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
470 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
508 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
471 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
509 if (loader_data == data) { |
472 if (loader_data == data) { |
541 ClassLoaderData* data = _head; |
504 ClassLoaderData* data = _head; |
542 ClassLoaderData* prev = NULL; |
505 ClassLoaderData* prev = NULL; |
543 bool seen_dead_loader = false; |
506 bool seen_dead_loader = false; |
544 uint loaders_processed = 0; |
507 uint loaders_processed = 0; |
545 uint loaders_removed = 0; |
508 uint loaders_removed = 0; |
546 |
|
547 // Save previous _unloading pointer for CMS which may add to unloading list before |
|
548 // purging and we don't want to rewalk the previously unloaded class loader data. |
|
549 _saved_unloading = _unloading; |
|
550 |
509 |
551 data = _head; |
510 data = _head; |
552 while (data != NULL) { |
511 while (data != NULL) { |
553 if (data->is_alive()) { |
512 if (data->is_alive()) { |
554 prev = data; |
513 prev = data; |