src/share/vm/classfile/classLoaderData.cpp

changeset 6992
2c6ef90f030a
parent 6974
556a06aec3fa
child 7333
b12a2a9b05ca
     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;

mercurial