RFR: 8212989: Allow CompiledMethod ExceptionCache have unloaded klasses

Erik Österlund erik.osterlund at oracle.com
Thu Nov 1 12:58:41 UTC 2018


The ExceptionCaches of compiled methods is traditionally pruned in 
safepoints during class unloading. This allows the exception cache to 
have lock-free reads, while performing inserts under a lock, and pruning 
under a safepoint. With concurrent class unloading, the exception caches 
need to be cleaned concurrently.

To retain the lock-free reads that seem good to keep lock-free, a 
lock-free cleaning mechanism was introduced. Only one thread per 
compiled method cleans each exception cache, but that thread races with 
both single writers (under the ExceptionCache_lock) and any number of 

The head of the exception cache list is concurrently cleaned by both 
inserting threads and cleaning threads. This allows having an invariant 
that no newly prepended entries ever produce next pointers to dead 
exception caches, that are concurrently removed from the list. As for 
the internal next pointers, they are only pruned by the one concurrent 
cleaning thread. This happens concurrent to reads that simply skip over 
dead entries as they have different Klass* pointers to the one being 
searched for.

The single concurrent cleanup thread does not delete things removed from 
the list straight away. Instead, they are placed on a purge list that is 
freed up after a subsequent global handshaking operation. That allows 
ABA-free CAS instructions in the lock-free paths, and allows safe 
concurrent reading of entries in the exception cache list.

Note that we already incorrectly "relied on memory_order_consume" for 
the head pointer. But it used a volatile load. Assuming volatile loads 
retain memory_order_consume semantics is not allowed in HotSpot runtime 
code, so I changed those loads to use acquire accordingly.




More information about the hotspot-dev mailing list