RFR: 8213209: [REDO] Allow Klass::_subklass and _next_sibling to have unloaded classes

Erik Österlund 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 mailing list