362 new_entry->set_next(exception_cache()); |
362 new_entry->set_next(exception_cache()); |
363 } |
363 } |
364 set_exception_cache(new_entry); |
364 set_exception_cache(new_entry); |
365 } |
365 } |
366 |
366 |
367 void nmethod::remove_from_exception_cache(ExceptionCache* ec) { |
367 void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) { |
368 ExceptionCache* prev = NULL; |
368 ExceptionCache* prev = NULL; |
369 ExceptionCache* curr = exception_cache(); |
369 ExceptionCache* curr = exception_cache(); |
370 assert(curr != NULL, "nothing to remove"); |
370 |
371 // find the previous and next entry of ec |
371 while (curr != NULL) { |
372 while (curr != ec) { |
372 ExceptionCache* next = curr->next(); |
373 prev = curr; |
373 |
374 curr = curr->next(); |
374 Klass* ex_klass = curr->exception_type(); |
375 assert(curr != NULL, "ExceptionCache not found"); |
375 if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { |
376 } |
376 if (prev == NULL) { |
377 // now: curr == ec |
377 set_exception_cache(next); |
378 ExceptionCache* next = curr->next(); |
378 } else { |
379 if (prev == NULL) { |
379 prev->set_next(next); |
380 set_exception_cache(next); |
380 } |
381 } else { |
381 delete curr; |
382 prev->set_next(next); |
382 // prev stays the same. |
383 } |
383 } else { |
384 delete curr; |
384 prev = curr; |
385 } |
385 } |
386 |
386 |
|
387 curr = next; |
|
388 } |
|
389 } |
387 |
390 |
388 // public method for accessing the exception cache |
391 // public method for accessing the exception cache |
389 // These are the public access methods. |
392 // These are the public access methods. |
390 address nmethod::handler_for_exception_and_pc(Handle exception, address pc) { |
393 address nmethod::handler_for_exception_and_pc(Handle exception, address pc) { |
391 // We never grab a lock to read the exception cache, so we may |
394 // We never grab a lock to read the exception cache, so we may |
1617 // of this nmethod is reported. |
1620 // of this nmethod is reported. |
1618 unloading_occurred = true; |
1621 unloading_occurred = true; |
1619 } |
1622 } |
1620 |
1623 |
1621 // Exception cache |
1624 // Exception cache |
1622 ExceptionCache* ec = exception_cache(); |
1625 clean_exception_cache(is_alive); |
1623 while (ec != NULL) { |
|
1624 Klass* ex_klass = ec->exception_type(); |
|
1625 ExceptionCache* next_ec = ec->next(); |
|
1626 if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { |
|
1627 remove_from_exception_cache(ec); |
|
1628 } |
|
1629 ec = next_ec; |
|
1630 } |
|
1631 |
1626 |
1632 // If class unloading occurred we first iterate over all inline caches and |
1627 // If class unloading occurred we first iterate over all inline caches and |
1633 // clear ICs where the cached oop is referring to an unloaded klass or method. |
1628 // clear ICs where the cached oop is referring to an unloaded klass or method. |
1634 // The remaining live cached oops will be traversed in the relocInfo::oop_type |
1629 // The remaining live cached oops will be traversed in the relocInfo::oop_type |
1635 // iteration below. |
1630 // iteration below. |