Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/classLoaderData.cpp @ 20278:2c6ef90f030a
8049421: G1 Class Unloading after completing a concurrent mark cycle
Reviewed-by: tschatzl, ehelin, brutisso, coleenp, roland, iveresov
Contributed-by: stefan.karlsson@oracle.com, mikael.gerdin@oracle.com
author | stefank |
---|---|
date | Mon, 07 Jul 2014 10:12:40 +0200 |
parents | 556a06aec3fa |
children | b12a2a9b05ca |
comparison
equal
deleted
inserted
replaced
20277:882004b9e7e1 | 20278:2c6ef90f030a |
---|---|
319 } | 319 } |
320 tty->print_cr("]"); | 320 tty->print_cr("]"); |
321 } | 321 } |
322 } | 322 } |
323 | 323 |
324 #ifdef ASSERT | |
325 class AllAliveClosure : public OopClosure { | |
326 BoolObjectClosure* _is_alive_closure; | |
327 bool _found_dead; | |
328 public: | |
329 AllAliveClosure(BoolObjectClosure* is_alive_closure) : _is_alive_closure(is_alive_closure), _found_dead(false) {} | |
330 template <typename T> void do_oop_work(T* p) { | |
331 T heap_oop = oopDesc::load_heap_oop(p); | |
332 if (!oopDesc::is_null(heap_oop)) { | |
333 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | |
334 if (!_is_alive_closure->do_object_b(obj)) { | |
335 _found_dead = true; | |
336 } | |
337 } | |
338 } | |
339 void do_oop(oop* p) { do_oop_work<oop>(p); } | |
340 void do_oop(narrowOop* p) { do_oop_work<narrowOop>(p); } | |
341 bool found_dead() { return _found_dead; } | |
342 }; | |
343 #endif | |
344 | |
324 oop ClassLoaderData::keep_alive_object() const { | 345 oop ClassLoaderData::keep_alive_object() const { |
325 assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); | 346 assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); |
326 return is_anonymous() ? _klasses->java_mirror() : class_loader(); | 347 return is_anonymous() ? _klasses->java_mirror() : class_loader(); |
327 } | 348 } |
328 | 349 |
329 bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const { | 350 bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const { |
330 bool alive = keep_alive() // null class loader and incomplete anonymous klasses. | 351 bool alive = keep_alive() // null class loader and incomplete anonymous klasses. |
331 || is_alive_closure->do_object_b(keep_alive_object()); | 352 || is_alive_closure->do_object_b(keep_alive_object()); |
332 | 353 |
333 assert(!alive || claimed(), "must be claimed"); | 354 #ifdef ASSERT |
355 if (alive) { | |
356 AllAliveClosure all_alive_closure(is_alive_closure); | |
357 KlassToOopClosure klass_closure(&all_alive_closure); | |
358 const_cast<ClassLoaderData*>(this)->oops_do(&all_alive_closure, &klass_closure, false); | |
359 assert(!all_alive_closure.found_dead(), err_msg("Found dead oop in alive cld: " PTR_FORMAT, p2i(this))); | |
360 } | |
361 #endif | |
362 | |
334 return alive; | 363 return alive; |
335 } | 364 } |
336 | 365 |
337 | 366 |
338 ClassLoaderData::~ClassLoaderData() { | 367 ClassLoaderData::~ClassLoaderData() { |
607 } | 636 } |
608 } | 637 } |
609 | 638 |
610 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { | 639 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
611 if (ClassUnloading) { | 640 if (ClassUnloading) { |
612 ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim); | 641 keep_alive_oops_do(f, klass_closure, must_claim); |
613 } else { | 642 } else { |
614 ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim); | 643 oops_do(f, klass_closure, must_claim); |
644 } | |
645 } | |
646 | |
647 void ClassLoaderDataGraph::cld_do(CLDClosure* cl) { | |
648 for (ClassLoaderData* cld = _head; cl != NULL && cld != NULL; cld = cld->next()) { | |
649 cl->do_cld(cld); | |
650 } | |
651 } | |
652 | |
653 void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) { | |
654 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->_next) { | |
655 CLDClosure* closure = cld->keep_alive() ? strong : weak; | |
656 if (closure != NULL) { | |
657 closure->do_cld(cld); | |
658 } | |
659 } | |
660 } | |
661 | |
662 void ClassLoaderDataGraph::keep_alive_cld_do(CLDClosure* cl) { | |
663 roots_cld_do(cl, NULL); | |
664 } | |
665 | |
666 void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) { | |
667 if (ClassUnloading) { | |
668 keep_alive_cld_do(cl); | |
669 } else { | |
670 cld_do(cl); | |
615 } | 671 } |
616 } | 672 } |
617 | 673 |
618 void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) { | 674 void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) { |
619 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { | 675 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
662 | 718 |
663 curr = curr->_next; | 719 curr = curr->_next; |
664 } | 720 } |
665 | 721 |
666 return array; | 722 return array; |
723 } | |
724 | |
725 bool ClassLoaderDataGraph::unload_list_contains(const void* x) { | |
726 assert(SafepointSynchronize::is_at_safepoint(), "only safe to call at safepoint"); | |
727 for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { | |
728 if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) { | |
729 return true; | |
730 } | |
731 } | |
732 return false; | |
667 } | 733 } |
668 | 734 |
669 #ifndef PRODUCT | 735 #ifndef PRODUCT |
670 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { | 736 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { |
671 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { | 737 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
784 Metaspace* ClassLoaderData::rw_metaspace() { | 850 Metaspace* ClassLoaderData::rw_metaspace() { |
785 assert(_rw_metaspace != NULL, "should already be initialized"); | 851 assert(_rw_metaspace != NULL, "should already be initialized"); |
786 return _rw_metaspace; | 852 return _rw_metaspace; |
787 } | 853 } |
788 | 854 |
855 ClassLoaderDataGraphKlassIteratorAtomic::ClassLoaderDataGraphKlassIteratorAtomic() | |
856 : _next_klass(NULL) { | |
857 ClassLoaderData* cld = ClassLoaderDataGraph::_head; | |
858 Klass* klass = NULL; | |
859 | |
860 // Find the first klass in the CLDG. | |
861 while (cld != NULL) { | |
862 klass = cld->_klasses; | |
863 if (klass != NULL) { | |
864 _next_klass = klass; | |
865 return; | |
866 } | |
867 cld = cld->next(); | |
868 } | |
869 } | |
870 | |
871 Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass) { | |
872 Klass* next = klass->next_link(); | |
873 if (next != NULL) { | |
874 return next; | |
875 } | |
876 | |
877 // No more klasses in the current CLD. Time to find a new CLD. | |
878 ClassLoaderData* cld = klass->class_loader_data(); | |
879 while (next == NULL) { | |
880 cld = cld->next(); | |
881 if (cld == NULL) { | |
882 break; | |
883 } | |
884 next = cld->_klasses; | |
885 } | |
886 | |
887 return next; | |
888 } | |
889 | |
890 Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() { | |
891 Klass* head = (Klass*)_next_klass; | |
892 | |
893 while (head != NULL) { | |
894 Klass* next = next_klass_in_cldg(head); | |
895 | |
896 Klass* old_head = (Klass*)Atomic::cmpxchg_ptr(next, &_next_klass, head); | |
897 | |
898 if (old_head == head) { | |
899 return head; // Won the CAS. | |
900 } | |
901 | |
902 head = old_head; | |
903 } | |
904 | |
905 // Nothing more for the iterator to hand out. | |
906 assert(head == NULL, err_msg("head is " PTR_FORMAT ", expected not null:", p2i(head))); | |
907 return NULL; | |
908 } | |
789 | 909 |
790 ClassLoaderDataGraphMetaspaceIterator::ClassLoaderDataGraphMetaspaceIterator() { | 910 ClassLoaderDataGraphMetaspaceIterator::ClassLoaderDataGraphMetaspaceIterator() { |
791 _data = ClassLoaderDataGraph::_head; | 911 _data = ClassLoaderDataGraph::_head; |
792 } | 912 } |
793 | 913 |