# HG changeset patch # User stefank # Date 1403622588 -7200 # Node ID 9717199cb8de058ea8c1291c0b7d67a7826fae0d # Parent 4c1b88a53c74456191ff7cefca89bf21b07a89e0 8047373: Clean the ExceptionCache in one pass Summary: Also-reviewed-by: kim.barrett@oracle.com Reviewed-by: jmasa, jwilhelm diff -r 4c1b88a53c74 -r 9717199cb8de src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Tue Jun 24 16:20:15 2014 +0200 +++ b/src/share/vm/code/nmethod.cpp Tue Jun 24 17:09:48 2014 +0200 @@ -384,27 +384,30 @@ 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"); + + 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; } - // now: curr == ec - ExceptionCache* next = curr->next(); - if (prev == NULL) { - set_exception_cache(next); - } else { - prev->set_next(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 @@ } // 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 -r 4c1b88a53c74 -r 9717199cb8de src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Tue Jun 24 16:20:15 2014 +0200 +++ b/src/share/vm/code/nmethod.hpp Tue Jun 24 17:09:48 2014 +0200 @@ -534,7 +534,7 @@ 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);