RFR: 8213565: Crash in DependencyContext::remove_dependent_nmethod

Erik Österlund erik.osterlund at oracle.com
Mon Nov 12 22:02:06 UTC 2018


Hi,

In my change 8209189, I moved a lot of code around relating to code 
cache unloading. Unfortunately, I failed to see that when making 
nmethods unloaded, and their dependents are flushed... they are not 
immediately removed. Instead, they are tagged to have stale entries, 
that are later cleaned during weak metadata cleaning of InstanceKlass. 
As for method handles, they leak instead, with some hacks to reduce the 
leaking by expunging entries while adding and removing.

Obviously, with InstanceKlass cleanup and code cache unloading now
possibly running in parallel after 8209189, things can go wrong. These 
two phases used
to be separated by a "wait barrier" for the worker threads preventing 
that parallelism.

The reason dependency contexts were not cleaned when they were found
during code cache cleaning, is because it was not thread safe when code
cache unloading was made parallel instead of serial. But now that we are
implementing concurrent class unloading, we are going to need concurrent
cleanup of dependency contexts anyway. Therefore I will propose a bug 
fix that fixes the problem in a way that works for both serial, parallel 
and concurrent class unloading.

The solution is to during code cache unloading claim cleaning of
encountered stale dependency contexts, and clean them straight away.
Entries are unlinked in a lock-free fashion, and placed on a purge list 
that is walked and deleted during ClassLoaderDataGraph::purge(). This 
follows the thinking of first unlinking, then syncing all threads, and 
then purging.

New accessors for the head and next links, hide is_unloading entries and 
helps unlinking them and putting them into the purge list.

Webrev:
http://cr.openjdk.java.net/~eosterlund/8213565/webrev.00/

Bug:
https://bugs.openjdk.java.net/browse/JDK-8213565

Thanks,
/Erik


More information about the hotspot-dev mailing list