mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
Merge
This commit is contained in:
commit
fbe6d80096
108 changed files with 3239 additions and 5213 deletions
|
@ -332,6 +332,27 @@ void ClassLoaderData::unload() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
class AllAliveClosure : public OopClosure {
|
||||
BoolObjectClosure* _is_alive_closure;
|
||||
bool _found_dead;
|
||||
public:
|
||||
AllAliveClosure(BoolObjectClosure* is_alive_closure) : _is_alive_closure(is_alive_closure), _found_dead(false) {}
|
||||
template <typename T> void do_oop_work(T* p) {
|
||||
T heap_oop = oopDesc::load_heap_oop(p);
|
||||
if (!oopDesc::is_null(heap_oop)) {
|
||||
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
|
||||
if (!_is_alive_closure->do_object_b(obj)) {
|
||||
_found_dead = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
void do_oop(oop* p) { do_oop_work<oop>(p); }
|
||||
void do_oop(narrowOop* p) { do_oop_work<narrowOop>(p); }
|
||||
bool found_dead() { return _found_dead; }
|
||||
};
|
||||
#endif
|
||||
|
||||
oop ClassLoaderData::keep_alive_object() const {
|
||||
assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");
|
||||
return is_anonymous() ? _klasses->java_mirror() : class_loader();
|
||||
|
@ -341,7 +362,15 @@ bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const {
|
|||
bool alive = keep_alive() // null class loader and incomplete anonymous klasses.
|
||||
|| is_alive_closure->do_object_b(keep_alive_object());
|
||||
|
||||
assert(!alive || claimed(), "must be claimed");
|
||||
#ifdef ASSERT
|
||||
if (alive) {
|
||||
AllAliveClosure all_alive_closure(is_alive_closure);
|
||||
KlassToOopClosure klass_closure(&all_alive_closure);
|
||||
const_cast<ClassLoaderData*>(this)->oops_do(&all_alive_closure, &klass_closure, false);
|
||||
assert(!all_alive_closure.found_dead(), err_msg("Found dead oop in alive cld: " PTR_FORMAT, p2i(this)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return alive;
|
||||
}
|
||||
|
||||
|
@ -620,9 +649,9 @@ void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, KlassClosure* klass
|
|||
|
||||
void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
|
||||
if (ClassUnloading) {
|
||||
ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim);
|
||||
keep_alive_oops_do(f, klass_closure, must_claim);
|
||||
} else {
|
||||
ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim);
|
||||
oops_do(f, klass_closure, must_claim);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,6 +661,27 @@ void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
|
|||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) {
|
||||
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->_next) {
|
||||
CLDClosure* closure = cld->keep_alive() ? strong : weak;
|
||||
if (closure != NULL) {
|
||||
closure->do_cld(cld);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::keep_alive_cld_do(CLDClosure* cl) {
|
||||
roots_cld_do(cl, NULL);
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) {
|
||||
if (ClassUnloading) {
|
||||
keep_alive_cld_do(cl);
|
||||
} else {
|
||||
cld_do(cl);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
|
||||
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
|
||||
cld->classes_do(klass_closure);
|
||||
|
@ -689,6 +739,16 @@ GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() {
|
|||
return array;
|
||||
}
|
||||
|
||||
bool ClassLoaderDataGraph::unload_list_contains(const void* x) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "only safe to call at safepoint");
|
||||
for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
|
||||
if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
|
||||
for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
|
||||
|
@ -809,6 +869,60 @@ Metaspace* ClassLoaderData::rw_metaspace() {
|
|||
return _rw_metaspace;
|
||||
}
|
||||
|
||||
ClassLoaderDataGraphKlassIteratorAtomic::ClassLoaderDataGraphKlassIteratorAtomic()
|
||||
: _next_klass(NULL) {
|
||||
ClassLoaderData* cld = ClassLoaderDataGraph::_head;
|
||||
Klass* klass = NULL;
|
||||
|
||||
// Find the first klass in the CLDG.
|
||||
while (cld != NULL) {
|
||||
klass = cld->_klasses;
|
||||
if (klass != NULL) {
|
||||
_next_klass = klass;
|
||||
return;
|
||||
}
|
||||
cld = cld->next();
|
||||
}
|
||||
}
|
||||
|
||||
Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass) {
|
||||
Klass* next = klass->next_link();
|
||||
if (next != NULL) {
|
||||
return next;
|
||||
}
|
||||
|
||||
// No more klasses in the current CLD. Time to find a new CLD.
|
||||
ClassLoaderData* cld = klass->class_loader_data();
|
||||
while (next == NULL) {
|
||||
cld = cld->next();
|
||||
if (cld == NULL) {
|
||||
break;
|
||||
}
|
||||
next = cld->_klasses;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() {
|
||||
Klass* head = (Klass*)_next_klass;
|
||||
|
||||
while (head != NULL) {
|
||||
Klass* next = next_klass_in_cldg(head);
|
||||
|
||||
Klass* old_head = (Klass*)Atomic::cmpxchg_ptr(next, &_next_klass, head);
|
||||
|
||||
if (old_head == head) {
|
||||
return head; // Won the CAS.
|
||||
}
|
||||
|
||||
head = old_head;
|
||||
}
|
||||
|
||||
// Nothing more for the iterator to hand out.
|
||||
assert(head == NULL, err_msg("head is " PTR_FORMAT ", expected not null:", p2i(head)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClassLoaderDataGraphMetaspaceIterator::ClassLoaderDataGraphMetaspaceIterator() {
|
||||
_data = ClassLoaderDataGraph::_head;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue