8047373: Clean the ExceptionCache in one pass

Also-reviewed-by: kim.barrett@oracle.com

Reviewed-by: jmasa, jwilhelm
This commit is contained in:
Stefan Karlsson 2014-06-24 17:09:48 +02:00
parent fd43773a10
commit b549ffc364
2 changed files with 22 additions and 27 deletions

View file

@ -364,26 +364,29 @@ void nmethod::add_exception_cache_entry(ExceptionCache* new_entry) {
set_exception_cache(new_entry);
}
void nmethod::remove_from_exception_cache(ExceptionCache* ec) {
void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) {
ExceptionCache* prev = NULL;
ExceptionCache* curr = exception_cache();
assert(curr != NULL, "nothing to remove");
// find the previous and next entry of ec
while (curr != ec) {
prev = curr;
curr = curr->next();
assert(curr != NULL, "ExceptionCache not found");
}
// now: curr == ec
ExceptionCache* next = curr->next();
if (prev == NULL) {
set_exception_cache(next);
} else {
prev->set_next(next);
}
delete curr;
}
while (curr != NULL) {
ExceptionCache* next = curr->next();
Klass* ex_klass = curr->exception_type();
if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
if (prev == NULL) {
set_exception_cache(next);
} else {
prev->set_next(next);
}
delete curr;
// prev stays the same.
} else {
prev = curr;
}
curr = next;
}
}
// public method for accessing the exception cache
// These are the public access methods.
@ -1619,15 +1622,7 @@ void nmethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred)
}
// Exception cache
ExceptionCache* ec = exception_cache();
while (ec != NULL) {
Klass* ex_klass = ec->exception_type();
ExceptionCache* next_ec = ec->next();
if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
remove_from_exception_cache(ec);
}
ec = next_ec;
}
clean_exception_cache(is_alive);
// 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.