RFR: 8213486: SIGSEGV in CompiledMethod::cleanup_inline_caches_impl with AOT

Erik Österlund erik.osterlund at oracle.com
Mon Nov 19 20:42:31 UTC 2018


Hi,

To aid code unloading, I introduced a new member function on 
CompiledMethod called is_unloading(). It calls oops_do to find if there 
are broken oops or not. During unloading, if a CompiledMethod 
is_unloading(), then we make_unloading(), otherwise we clean caches.

For this to work, it is assumed that all is_alive() CompiledMethods are 
visited during code cache unloading, so that later on, you can ask 
is_alive() CompiledMethods if they are is_unloading().

...except it looks like for AOTCompiledMethods when running with tiered 
compilation, may first be is_alive(), then become !is_alive() for a 
while, and then get resurrected to is_alive() using make_entrant(). This 
is normally fine, because IC caches are cleaned between resurrections, 
and the oops are held strongly live. But it messes with the 
is_unloading() state since while it is temporarily dead, these methods 
are not visited by code cache unloading, and hence don't get 
is_unloading() evaluated, and the epoch counters get messed up. So once 
the method gets resurrected using make_entrant(), we incorrectly ask to 
re-evaluate the operation outside of safepoints even for STW-unloading 
collectors.

Since for AOTCompiledMethods, we really just want to return false (these 
ones are not unloaded, and the oops are strong roots), I simply moved 
the epoched is_unloading() mechanism to nmethod, and let 
AOTCompiledMethod simply return false, allowing its wonky life cycle to 
not cause trouble.

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

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

Thanks,
/Erik


More information about the hotspot-dev mailing list