78 #include "utilities/ostream.hpp" |
78 #include "utilities/ostream.hpp" |
79 #if INCLUDE_TRACE |
79 #if INCLUDE_TRACE |
80 #include "trace/tracing.hpp" |
80 #include "trace/tracing.hpp" |
81 #endif |
81 #endif |
82 |
82 |
|
83 volatile size_t ClassLoaderDataGraph::_num_array_classes = 0; |
|
84 volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0; |
|
85 |
83 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; |
86 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; |
84 |
87 |
85 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : |
88 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : |
86 _class_loader(h_class_loader()), |
89 _class_loader(h_class_loader()), |
87 _is_anonymous(is_anonymous), |
90 _is_anonymous(is_anonymous), |
441 Klass* old_value = _klasses; |
444 Klass* old_value = _klasses; |
442 k->set_next_link(old_value); |
445 k->set_next_link(old_value); |
443 // Link the new item into the list, making sure the linked class is stable |
446 // Link the new item into the list, making sure the linked class is stable |
444 // since the list can be walked without a lock |
447 // since the list can be walked without a lock |
445 OrderAccess::release_store(&_klasses, k); |
448 OrderAccess::release_store(&_klasses, k); |
|
449 if (k->is_array_klass()) { |
|
450 ClassLoaderDataGraph::inc_array_classes(1); |
|
451 } else { |
|
452 ClassLoaderDataGraph::inc_instance_classes(1); |
|
453 } |
446 } |
454 } |
447 |
455 |
448 if (publicize && k->class_loader_data() != NULL) { |
456 if (publicize && k->class_loader_data() != NULL) { |
449 ResourceMark rm; |
457 ResourceMark rm; |
450 log_trace(class, loader, data)("Adding k: " PTR_FORMAT " %s to CLD: " |
458 log_trace(class, loader, data)("Adding k: " PTR_FORMAT " %s to CLD: " |
466 |
474 |
467 ClassLoaderDataGraphKlassIteratorStatic() : _current_loader_data(NULL), _current_class_entry(NULL) {} |
475 ClassLoaderDataGraphKlassIteratorStatic() : _current_loader_data(NULL), _current_class_entry(NULL) {} |
468 |
476 |
469 InstanceKlass* try_get_next_class() { |
477 InstanceKlass* try_get_next_class() { |
470 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); |
478 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); |
471 int max_classes = InstanceKlass::number_of_instance_classes(); |
479 size_t max_classes = ClassLoaderDataGraph::num_instance_classes(); |
472 assert(max_classes > 0, "should not be called with no instance classes"); |
480 assert(max_classes > 0, "should not be called with no instance classes"); |
473 for (int i = 0; i < max_classes; ) { |
481 for (size_t i = 0; i < max_classes; ) { |
474 |
482 |
475 if (_current_class_entry != NULL) { |
483 if (_current_class_entry != NULL) { |
476 Klass* k = _current_class_entry; |
484 Klass* k = _current_class_entry; |
477 _current_class_entry = _current_class_entry->next_link(); |
485 _current_class_entry = _current_class_entry->next_link(); |
478 |
486 |
543 _klasses = k->next_link(); |
551 _klasses = k->next_link(); |
544 } else { |
552 } else { |
545 Klass* next = k->next_link(); |
553 Klass* next = k->next_link(); |
546 prev->set_next_link(next); |
554 prev->set_next_link(next); |
547 } |
555 } |
|
556 |
|
557 if (k->is_array_klass()) { |
|
558 ClassLoaderDataGraph::dec_array_classes(1); |
|
559 } else { |
|
560 ClassLoaderDataGraph::dec_instance_classes(1); |
|
561 } |
|
562 |
548 return; |
563 return; |
549 } |
564 } |
550 prev = k; |
565 prev = k; |
551 assert(k != k->next_link(), "no loops!"); |
566 assert(k != k->next_link(), "no loops!"); |
552 } |
567 } |
637 || is_alive_closure->do_object_b(keep_alive_object()); |
652 || is_alive_closure->do_object_b(keep_alive_object()); |
638 |
653 |
639 return alive; |
654 return alive; |
640 } |
655 } |
641 |
656 |
|
657 class ReleaseKlassClosure: public KlassClosure { |
|
658 private: |
|
659 size_t _instance_class_released; |
|
660 size_t _array_class_released; |
|
661 public: |
|
662 ReleaseKlassClosure() : _instance_class_released(0), _array_class_released(0) { } |
|
663 |
|
664 size_t instance_class_released() const { return _instance_class_released; } |
|
665 size_t array_class_released() const { return _array_class_released; } |
|
666 |
|
667 void do_klass(Klass* k) { |
|
668 if (k->is_array_klass()) { |
|
669 _array_class_released ++; |
|
670 } else { |
|
671 assert(k->is_instance_klass(), "Must be"); |
|
672 _instance_class_released ++; |
|
673 InstanceKlass::release_C_heap_structures(InstanceKlass::cast(k)); |
|
674 } |
|
675 } |
|
676 }; |
|
677 |
642 ClassLoaderData::~ClassLoaderData() { |
678 ClassLoaderData::~ClassLoaderData() { |
643 // Release C heap structures for all the classes. |
679 // Release C heap structures for all the classes. |
644 classes_do(InstanceKlass::release_C_heap_structures); |
680 ReleaseKlassClosure cl; |
|
681 classes_do(&cl); |
|
682 |
|
683 ClassLoaderDataGraph::dec_array_classes(cl.array_class_released()); |
|
684 ClassLoaderDataGraph::dec_instance_classes(cl.instance_class_released()); |
645 |
685 |
646 // Release C heap allocated hashtable for all the packages. |
686 // Release C heap allocated hashtable for all the packages. |
647 if (_packages != NULL) { |
687 if (_packages != NULL) { |
648 // Destroy the table itself |
688 // Destroy the table itself |
649 delete _packages; |
689 delete _packages; |