8201537: Remove is_alive closure from Klass::is_loader_alive()

Remove is_alive closure from callers of Klass::is_loader_alive so that cleaning metadata doesn't require GC closure.

Reviewed-by: adinn, stefank
This commit is contained in:
Coleen Phillimore 2018-04-18 13:37:39 -04:00
parent 4ffd5d45c1
commit c215aa5889
18 changed files with 130 additions and 174 deletions

View file

@ -99,7 +99,7 @@ void CompiledMethod::add_exception_cache_entry(ExceptionCache* new_entry) {
release_set_exception_cache(new_entry);
}
void CompiledMethod::clean_exception_cache(BoolObjectClosure* is_alive) {
void CompiledMethod::clean_exception_cache() {
ExceptionCache* prev = NULL;
ExceptionCache* curr = exception_cache();
@ -107,7 +107,7 @@ void CompiledMethod::clean_exception_cache(BoolObjectClosure* is_alive) {
ExceptionCache* next = curr->next();
Klass* ex_klass = curr->exception_type();
if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
if (ex_klass != NULL && !ex_klass->is_loader_alive()) {
if (prev == NULL) {
set_exception_cache(next);
} else {
@ -369,56 +369,42 @@ void CompiledMethod::clear_ic_stubs() {
}
#ifdef ASSERT
class CheckClass : AllStatic {
static BoolObjectClosure* _is_alive;
// Check class_loader is alive for this bit of metadata.
static void check_class(Metadata* md) {
Klass* klass = NULL;
if (md->is_klass()) {
klass = ((Klass*)md);
} else if (md->is_method()) {
klass = ((Method*)md)->method_holder();
} else if (md->is_methodData()) {
klass = ((MethodData*)md)->method()->method_holder();
} else {
md->print();
ShouldNotReachHere();
}
assert(klass->is_loader_alive(_is_alive), "must be alive");
}
public:
static void do_check_class(BoolObjectClosure* is_alive, CompiledMethod* nm) {
assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint");
_is_alive = is_alive;
nm->metadata_do(check_class);
}
};
// This is called during a safepoint so can use static data
BoolObjectClosure* CheckClass::_is_alive = NULL;
// Check class_loader is alive for this bit of metadata.
static void check_class(Metadata* md) {
Klass* klass = NULL;
if (md->is_klass()) {
klass = ((Klass*)md);
} else if (md->is_method()) {
klass = ((Method*)md)->method_holder();
} else if (md->is_methodData()) {
klass = ((MethodData*)md)->method()->method_holder();
} else {
md->print();
ShouldNotReachHere();
}
assert(klass->is_loader_alive(), "must be alive");
}
#endif // ASSERT
void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) {
void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) {
if (ic->is_icholder_call()) {
// The only exception is compiledICHolder oops which may
// yet be marked below. (We check this further below).
CompiledICHolder* cichk_oop = ic->cached_icholder();
if (cichk_oop->is_loader_alive(is_alive)) {
if (cichk_oop->is_loader_alive()) {
return;
}
} else {
Metadata* ic_oop = ic->cached_metadata();
if (ic_oop != NULL) {
if (ic_oop->is_klass()) {
if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
if (((Klass*)ic_oop)->is_loader_alive()) {
return;
}
} else if (ic_oop->is_method()) {
if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
if (((Method*)ic_oop)->method_holder()->is_loader_alive()) {
return;
}
} else {
@ -453,7 +439,7 @@ unsigned char CompiledMethod::unloading_clock() {
// all strong references alive. Any weak references should have been
// cleared as well. Visit all the metadata and ensure that it's
// really alive.
void CompiledMethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) {
void CompiledMethod::verify_metadata_loaders(address low_boundary) {
#ifdef ASSERT
RelocIterator iter(this, low_boundary);
while (iter.next()) {
@ -483,7 +469,7 @@ void CompiledMethod::verify_metadata_loaders(address low_boundary, BoolObjectClo
}
}
// Check that the metadata embedded in the nmethod is alive
CheckClass::do_check_class(is_alive, this);
metadata_do(check_class);
#endif
}
@ -518,7 +504,7 @@ void CompiledMethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_oc
}
// Exception cache
clean_exception_cache(is_alive);
clean_exception_cache();
// If class unloading occurred we first iterate over all inline caches and
// clear ICs where the cached oop is referring to an unloaded klass or method.
@ -529,7 +515,7 @@ void CompiledMethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_oc
while(iter.next()) {
if (iter.type() == relocInfo::virtual_call_type) {
CompiledIC *ic = CompiledIC_at(&iter);
clean_ic_if_metadata_is_dead(ic, is_alive);
clean_ic_if_metadata_is_dead(ic);
}
}
}
@ -545,7 +531,7 @@ void CompiledMethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_oc
#endif
// Ensure that all metadata is still alive
verify_metadata_loaders(low_boundary, is_alive);
verify_metadata_loaders(low_boundary);
}
template <class CompiledICorStaticCall>
@ -606,7 +592,7 @@ bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unl
}
// Exception cache
clean_exception_cache(is_alive);
clean_exception_cache();
bool postponed = false;
@ -619,7 +605,7 @@ bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unl
if (unloading_occurred) {
// If class unloading occurred we first iterate over all inline caches and
// clear ICs where the cached oop is referring to an unloaded klass or method.
clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive);
clean_ic_if_metadata_is_dead(CompiledIC_at(&iter));
}
postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
@ -656,7 +642,7 @@ bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unl
#endif
// Ensure that all metadata is still alive
verify_metadata_loaders(low_boundary, is_alive);
verify_metadata_loaders(low_boundary);
return postponed;
}