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