[External] : Re: API to create a new Allocate node?

John Rose john.r.rose at oracle.com
Fri Apr 29 19:20:37 UTC 2022


On 29 Apr 2022, at 10:23, Cesar Soares Lucas wrote:

> HI John.
>
> Thanks for the heads up! I'm not very familiar with all aspects of deoptimization, so I have a few questions.
>
> 1. Assuming I don't use GraphKit. Why do I need to construct a JVMS at the merge point? Is it because of the Allocate call will require an JVMS?

GraphKit makes it easier to provide needed JVMS’s at all safepoints.

(A safepoint is a call to a Java method, or to a VM entry point that “traps”.  Note that inner loop safepoints, when they are needed, call the VM.)

Any safepoint can deoptimize for various reasons, including reasons that are completely non-local relative to the particular JVMS of the safepoint.  Deoptimizations are (by design) rare but they can still happen.  If there is any missing or invalid information in a safepoint, and deopt gets triggered, the interpreter will run on invalid data and that will produce crashes or invalid computation.

(A classic case of non-local deopt:  Your compile task inlined 101 different methods.  One of those methods has a devirtualized method call, because the JIT concluded from CHA that there are no overrides.  A millisecond later, another class file is loaded, which includes an override for that method call.  Before that class file can create instances, the previous compile task must be invalidated, and code for all 101 methods discarded, and all threads executing that code must be converted to use some other execution mode—the interpreter via deoptimization.  Such threads are converted at safepoints, since those are the only places where there are recorded JVMS’s that can be used to pack the interpreter frames.  Now, suppose you are unlucky, so that one of your injected allocation sites is chosen as the deopt site.  What does the interpreter get as its state?  How does the computation roll forward?  This line of thought suggests a way to relax the restrictions:  If the JVM is considering a deopt event at a given safepoint S, and it somehow detects that the JVMS data for S is incomplete, it can “let go” and allow S to continue rolling forward in the existing code, in the hope that a complete safepoint S’ will soon be encountered.  But AFAIK we don’t do stuff like that now.)

So it’s never OK to provide anything other than a fully accurate JVMS to a safepoint.  If you don’t use GraphKit you still have to come up with a working JVMS if you insert a safepoint of any kind into the IR.

(Maybe the above restrictions have been relaxed recently, but I don’t think so.)

> 2. My plan was to just use the newly allocated object to replace the "local" value created by the "phi".

A few years from now, in the field, the JVMS for that allocation will be used in a deopt event.  (If we are lucky and do enough deopt-a-lot testing, we’ll find it during PIT.)  What JVMS will the interpreter execute when that happens?  If you can find an answer to that question, use that JVMS for the injected allocation site.

HTH

— John


More information about the hotspot-compiler-dev mailing list