diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp index 96d7b94cc8275d060192c33f749633d11c561fe6..2a878464afae73ebf042cc827323215e897ddd15 100644 --- a/src/share/vm/code/nmethod.cpp +++ b/src/share/vm/code/nmethod.cpp @@ -384,27 +384,30 @@ 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); + + 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; } - delete curr; } - // public method for accessing the exception cache // These are the public access methods. address nmethod::handler_for_exception_and_pc(Handle exception, address pc) { @@ -1650,15 +1653,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. diff --git a/src/share/vm/code/nmethod.hpp b/src/share/vm/code/nmethod.hpp index d75edad1036fc7f00552367aca5475562357c4e7..d12fe16ac463f1fc0199e1a8145e922a99b28a0e 100644 --- a/src/share/vm/code/nmethod.hpp +++ b/src/share/vm/code/nmethod.hpp @@ -534,7 +534,7 @@ public: void set_exception_cache(ExceptionCache *ec) { _exception_cache = ec; } address handler_for_exception_and_pc(Handle exception, address pc); void add_handler_for_exception_and_pc(Handle exception, address pc, address handler); - void remove_from_exception_cache(ExceptionCache* ec); + void clean_exception_cache(BoolObjectClosure* is_alive); // implicit exceptions support address continuation_for_implicit_exception(address pc);