RFR: 8247992: [JVMCI] HotSpotNmethod.executeVarargs can try execute a zombie nmethod
Erik Österlund
erik.osterlund at oracle.com
Mon Jun 22 13:49:47 UTC 2020
Hi Doug,
It would be nice if we could get rid of some cluttering of nested
#if JVMCI
if (blah) {
#endif
...
#if JVMCI
}
#endif
It makes it hard to read for (to me) no obvious reason.
Here is a patch on top of yours to remove some of that:
http://cr.openjdk.java.net/~eosterlund/8247992/webrev.doug..00/
Full webrev:
http://cr.openjdk.java.net/~eosterlund/8247992/webrev.00/
The reasoning in my changes is that since the SharedRuntime wrong method
handler has no idea about these alternative call targets, checking if
the nmethod is still entrant right before the call, will not guarantee
that we actually end up calling the target nmethod anyway. It could get
made not entrant just after the call, but before executing the first
instruction, which when becoming not entrant jumps to the wrong method
handler, which has no clue about any of this and just re-routes the call
to the currently best method code of the method used in the Java call
wrapper, without throwing any exception. So either we can live with
that, or we can not. If we can live with that, then all exception
handling can (and should) be removed from the Java call wrapper, because
it is not needed. Instead, we check if the nmethod is still entrant in
the JVMCI caller function, and accept that it could subsequently become
not entrant at any point in time. A few more instructions for a slippery
race to happen, but not worth cluttering the call wrapper with JVMCI
code over the difference.
Now I don't know how this API is used, but would it make sense to
instead check *after* the nmethod has been executed, if it is still
in_use()? Then we know that the nmethod has been executed to completion
without getting killed off, if we do not get an exception. And if we get
an exception then it got deoptimized either right before calling, or
during its execution. Like this:
http://cr.openjdk.java.net/~eosterlund/8247992/webrev.00..01/
That would completely close the window for that race, but assumes the
caller is okay with getting an exception if the nmethod gets deoptimized
while running. You know this API better than I do, so that's your call
if it is a good idea or not.
Thanks,
/Erik
On 2020-06-22 13:12, Doug Simon wrote:
> Hi, can I please get some reviews for this patch that fixes a race
> described in JDK-8247992
> <https://bugs.openjdk.java.net/browse/JDK-8247992>.
>
> The fix in the patch is to pass the HotSpotNmethod mirror object (in a
> handle) through the problematic VM-to-Java transition and only after
> the transition will the verified entry point be extracted from the
> mirror. This will prevent a zombie nmethod from being executed.
>
> It’s still possible for the call to not reach the “alternative target”
> due to sweeping heuristics. This is an acceptable limitation of having
> an alternative call target in JavaCallWrapper. It could be fixed by
> altering CPU specific i2c trampoline code but the added complexity is
> not worth it for this test-only mechanism. Tests using this API can
> detect whether the alternative target was actually called if they
> really care about it.
>
> Thanks to Erik Osterlund for the in-depth analysis and suggested
> solutions.
>
> https://dougxc.github.io/webrevs/8247992_16/index.html
> https://bugs.openjdk.java.net/browse/JDK-8247992
>
> Testing: hs-tier1,hs-tier2,hs-tier3-graal
>
> -Doug
More information about the hotspot-compiler-dev
mailing list