8047373: Clean the ExceptionCache in one pass

Tue, 24 Jun 2014 17:09:48 +0200

author
stefank
date
Tue, 24 Jun 2014 17:09:48 +0200
changeset 6983
9717199cb8de
parent 6982
4c1b88a53c74
child 6984
b7d24d2bc8be

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);

mercurial