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