RFR: 8213209: [REDO] Allow Klass::_subklass and _next_sibling to have unloaded classes
erik.osterlund at oracle.com
Fri Nov 16 18:12:01 UTC 2018
This is a redo of Coleen's earlier patch to clean weak metadata links
using the Compile_lock.
We noticed the proposed solution could cause deadlocks. At least one of
the reasons for that is that the Compile_lock was taken during printing
and verification in safepoints. And the Compile_lock is sometimes held
while issuing safepoints. The latter problem also forces us to take the
Compile_lock before joining the suspendible thread set, to avoid another
deadlock situation. But that is really nasty for other reasons. And
there have been a few more problems as well.
So in this case, we think it is both safer, less error prone, and better
performing (although less important) to perform this cleaning in a
lock-free fashion rather than trying to dodge all the issues related to
the locking protocol.
Inserts still require a lock. Therefore, we are dealing with lock-free
reads, and lock-free cleaning. The lock-free cleaning is interacting
with multiple lock-free readers and a single writer.
The single inserter always helps with cleaning the subclass list head
before prepending new nodes to the chain. That allows an invariant that
the siblings link is never inserted pointing at a Klass that is
unloading, which simplifies things a lot. The head is inserted in a
classic load + CAS in a loop.
Readers require load_acquire when reading the head, due to competing
inserts putting new Klass pointers there. The siblings, however, only
need relaxed consistency, because they are linked to data strictly older
than the head, which has already been acquired.
Unlinked entries are all inserted into a purge list, because freeing
them immediately is not safe. A global handshake operation is performed,
and after that ClassLoaderDataGraph::purge() will go through the list
and delete the entries safely.
More information about the hotspot-dev