Tue, 24 Jun 2014 17:09:48 +0200
8047373: Clean the ExceptionCache in one pass
Summary: Also-reviewed-by: kim.barrett@oracle.com
Reviewed-by: jmasa, jwilhelm
src/share/vm/code/nmethod.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/code/nmethod.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/code/nmethod.cpp Tue Jun 24 16:20:15 2014 +0200 1.2 +++ b/src/share/vm/code/nmethod.cpp Tue Jun 24 17:09:48 2014 +0200 1.3 @@ -384,27 +384,30 @@ 1.4 set_exception_cache(new_entry); 1.5 } 1.6 1.7 -void nmethod::remove_from_exception_cache(ExceptionCache* ec) { 1.8 +void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) { 1.9 ExceptionCache* prev = NULL; 1.10 ExceptionCache* curr = exception_cache(); 1.11 - assert(curr != NULL, "nothing to remove"); 1.12 - // find the previous and next entry of ec 1.13 - while (curr != ec) { 1.14 - prev = curr; 1.15 - curr = curr->next(); 1.16 - assert(curr != NULL, "ExceptionCache not found"); 1.17 + 1.18 + while (curr != NULL) { 1.19 + ExceptionCache* next = curr->next(); 1.20 + 1.21 + Klass* ex_klass = curr->exception_type(); 1.22 + if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { 1.23 + if (prev == NULL) { 1.24 + set_exception_cache(next); 1.25 + } else { 1.26 + prev->set_next(next); 1.27 + } 1.28 + delete curr; 1.29 + // prev stays the same. 1.30 + } else { 1.31 + prev = curr; 1.32 + } 1.33 + 1.34 + curr = next; 1.35 } 1.36 - // now: curr == ec 1.37 - ExceptionCache* next = curr->next(); 1.38 - if (prev == NULL) { 1.39 - set_exception_cache(next); 1.40 - } else { 1.41 - prev->set_next(next); 1.42 - } 1.43 - delete curr; 1.44 } 1.45 1.46 - 1.47 // public method for accessing the exception cache 1.48 // These are the public access methods. 1.49 address nmethod::handler_for_exception_and_pc(Handle exception, address pc) { 1.50 @@ -1650,15 +1653,7 @@ 1.51 } 1.52 1.53 // Exception cache 1.54 - ExceptionCache* ec = exception_cache(); 1.55 - while (ec != NULL) { 1.56 - Klass* ex_klass = ec->exception_type(); 1.57 - ExceptionCache* next_ec = ec->next(); 1.58 - if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { 1.59 - remove_from_exception_cache(ec); 1.60 - } 1.61 - ec = next_ec; 1.62 - } 1.63 + clean_exception_cache(is_alive); 1.64 1.65 // If class unloading occurred we first iterate over all inline caches and 1.66 // clear ICs where the cached oop is referring to an unloaded klass or method.
2.1 --- a/src/share/vm/code/nmethod.hpp Tue Jun 24 16:20:15 2014 +0200 2.2 +++ b/src/share/vm/code/nmethod.hpp Tue Jun 24 17:09:48 2014 +0200 2.3 @@ -534,7 +534,7 @@ 2.4 void set_exception_cache(ExceptionCache *ec) { _exception_cache = ec; } 2.5 address handler_for_exception_and_pc(Handle exception, address pc); 2.6 void add_handler_for_exception_and_pc(Handle exception, address pc, address handler); 2.7 - void remove_from_exception_cache(ExceptionCache* ec); 2.8 + void clean_exception_cache(BoolObjectClosure* is_alive); 2.9 2.10 // implicit exceptions support 2.11 address continuation_for_implicit_exception(address pc);