1.1 --- a/src/share/vm/classfile/classLoaderData.cpp Tue Jul 01 09:03:55 2014 +0200 1.2 +++ b/src/share/vm/classfile/classLoaderData.cpp Mon Jul 07 10:12:40 2014 +0200 1.3 @@ -321,6 +321,27 @@ 1.4 } 1.5 } 1.6 1.7 +#ifdef ASSERT 1.8 +class AllAliveClosure : public OopClosure { 1.9 + BoolObjectClosure* _is_alive_closure; 1.10 + bool _found_dead; 1.11 + public: 1.12 + AllAliveClosure(BoolObjectClosure* is_alive_closure) : _is_alive_closure(is_alive_closure), _found_dead(false) {} 1.13 + template <typename T> void do_oop_work(T* p) { 1.14 + T heap_oop = oopDesc::load_heap_oop(p); 1.15 + if (!oopDesc::is_null(heap_oop)) { 1.16 + oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); 1.17 + if (!_is_alive_closure->do_object_b(obj)) { 1.18 + _found_dead = true; 1.19 + } 1.20 + } 1.21 + } 1.22 + void do_oop(oop* p) { do_oop_work<oop>(p); } 1.23 + void do_oop(narrowOop* p) { do_oop_work<narrowOop>(p); } 1.24 + bool found_dead() { return _found_dead; } 1.25 +}; 1.26 +#endif 1.27 + 1.28 oop ClassLoaderData::keep_alive_object() const { 1.29 assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); 1.30 return is_anonymous() ? _klasses->java_mirror() : class_loader(); 1.31 @@ -330,7 +351,15 @@ 1.32 bool alive = keep_alive() // null class loader and incomplete anonymous klasses. 1.33 || is_alive_closure->do_object_b(keep_alive_object()); 1.34 1.35 - assert(!alive || claimed(), "must be claimed"); 1.36 +#ifdef ASSERT 1.37 + if (alive) { 1.38 + AllAliveClosure all_alive_closure(is_alive_closure); 1.39 + KlassToOopClosure klass_closure(&all_alive_closure); 1.40 + const_cast<ClassLoaderData*>(this)->oops_do(&all_alive_closure, &klass_closure, false); 1.41 + assert(!all_alive_closure.found_dead(), err_msg("Found dead oop in alive cld: " PTR_FORMAT, p2i(this))); 1.42 + } 1.43 +#endif 1.44 + 1.45 return alive; 1.46 } 1.47 1.48 @@ -609,9 +638,36 @@ 1.49 1.50 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { 1.51 if (ClassUnloading) { 1.52 - ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim); 1.53 + keep_alive_oops_do(f, klass_closure, must_claim); 1.54 } else { 1.55 - ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim); 1.56 + oops_do(f, klass_closure, must_claim); 1.57 + } 1.58 +} 1.59 + 1.60 +void ClassLoaderDataGraph::cld_do(CLDClosure* cl) { 1.61 + for (ClassLoaderData* cld = _head; cl != NULL && cld != NULL; cld = cld->next()) { 1.62 + cl->do_cld(cld); 1.63 + } 1.64 +} 1.65 + 1.66 +void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) { 1.67 + for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->_next) { 1.68 + CLDClosure* closure = cld->keep_alive() ? strong : weak; 1.69 + if (closure != NULL) { 1.70 + closure->do_cld(cld); 1.71 + } 1.72 + } 1.73 +} 1.74 + 1.75 +void ClassLoaderDataGraph::keep_alive_cld_do(CLDClosure* cl) { 1.76 + roots_cld_do(cl, NULL); 1.77 +} 1.78 + 1.79 +void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) { 1.80 + if (ClassUnloading) { 1.81 + keep_alive_cld_do(cl); 1.82 + } else { 1.83 + cld_do(cl); 1.84 } 1.85 } 1.86 1.87 @@ -666,6 +722,16 @@ 1.88 return array; 1.89 } 1.90 1.91 +bool ClassLoaderDataGraph::unload_list_contains(const void* x) { 1.92 + assert(SafepointSynchronize::is_at_safepoint(), "only safe to call at safepoint"); 1.93 + for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) { 1.94 + if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) { 1.95 + return true; 1.96 + } 1.97 + } 1.98 + return false; 1.99 +} 1.100 + 1.101 #ifndef PRODUCT 1.102 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { 1.103 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { 1.104 @@ -786,6 +852,60 @@ 1.105 return _rw_metaspace; 1.106 } 1.107 1.108 +ClassLoaderDataGraphKlassIteratorAtomic::ClassLoaderDataGraphKlassIteratorAtomic() 1.109 + : _next_klass(NULL) { 1.110 + ClassLoaderData* cld = ClassLoaderDataGraph::_head; 1.111 + Klass* klass = NULL; 1.112 + 1.113 + // Find the first klass in the CLDG. 1.114 + while (cld != NULL) { 1.115 + klass = cld->_klasses; 1.116 + if (klass != NULL) { 1.117 + _next_klass = klass; 1.118 + return; 1.119 + } 1.120 + cld = cld->next(); 1.121 + } 1.122 +} 1.123 + 1.124 +Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass) { 1.125 + Klass* next = klass->next_link(); 1.126 + if (next != NULL) { 1.127 + return next; 1.128 + } 1.129 + 1.130 + // No more klasses in the current CLD. Time to find a new CLD. 1.131 + ClassLoaderData* cld = klass->class_loader_data(); 1.132 + while (next == NULL) { 1.133 + cld = cld->next(); 1.134 + if (cld == NULL) { 1.135 + break; 1.136 + } 1.137 + next = cld->_klasses; 1.138 + } 1.139 + 1.140 + return next; 1.141 +} 1.142 + 1.143 +Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() { 1.144 + Klass* head = (Klass*)_next_klass; 1.145 + 1.146 + while (head != NULL) { 1.147 + Klass* next = next_klass_in_cldg(head); 1.148 + 1.149 + Klass* old_head = (Klass*)Atomic::cmpxchg_ptr(next, &_next_klass, head); 1.150 + 1.151 + if (old_head == head) { 1.152 + return head; // Won the CAS. 1.153 + } 1.154 + 1.155 + head = old_head; 1.156 + } 1.157 + 1.158 + // Nothing more for the iterator to hand out. 1.159 + assert(head == NULL, err_msg("head is " PTR_FORMAT ", expected not null:", p2i(head))); 1.160 + return NULL; 1.161 +} 1.162 1.163 ClassLoaderDataGraphMetaspaceIterator::ClassLoaderDataGraphMetaspaceIterator() { 1.164 _data = ClassLoaderDataGraph::_head;