API to create a new Allocate node?

Cesar Soares Lucas Divino.Cesar at microsoft.com
Fri Apr 29 17:23:46 UTC 2022


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? 
2. My plan was to just use the newly allocated object to replace the "local" value created by the "phi".


Thanks,
Cesar

________________________________________
From: John Rose <john.r.rose at oracle.com>
Sent: April 28, 2022 3:52 PM
To: Cesar Soares Lucas
Cc: Vladimir Kozlov; hotspot-compiler-dev at openjdk.java.net
Subject: Re: API to create a new Allocate node?

On 28 Apr 2022, at 14:29, Cesar Soares Lucas wrote:

Thanks, Vladimir.

Do you have correct jvm state at the point of insertion (to deoptimize correctly if needed)?

I think I do. Is that the only requirement for getting GraphKit to work properly outside parsing? Generally speaking is it fair game to use GraphKit outside the parsing phase?

Did you look on examples in `PhaseStringOpts::replace_string_concat`?:

Yeah, I looked at a few examples and I'm able to instantiate it. However, I got some SEGFAULT when new_instance tries to create new nodes.

I suggest to clone original Allocate node (if you have it) and adjust its edges (input and outputs) if needed.

I'll try that. Thanks! However, the biggest challenge seems to be which node is the correct node to connect the edges to/from!

FYI, basically what I'm trying to do is to insert an object allocation at the place where we have an object allocation merge. Then later I'll initialize the fields of the newly allocated objects using phi functions for each individual field. etc.

Here’s what I think might be an example of such an object allocation merge:

Point obj;
if (z) {
   obj = new Point(1,2);
   foo();
} else {
   bar();
   obj = new Point(3,4);
}
M:
obj = new Point(Phi[M,1,3], Phi[M,2,4]);


The merge point also combines up side effects from things like foo and bar.

There is no way to construct a JVM state that merges just the two allocation states, for the simple reason that JVM states (as used for deoptimization or stack walking) always correspond to one BCI, with all side effects posted up to that unique point; a JVM state is never a pure logical merge of two other states, except in during abstract interpretation when side effects are being fully modeled. So there’s no way to create the JVM state for the third allocation by directly composing the states from the first two.

Instead, you have to try to pick the correct JVM state for the new allocation (at M) in such a way that, if and when deoptimization happens, the interpreter starts at the right BCI, that for M. (The deoptimization logic will create the third Point instance from the stored Phi values, as displayed in the debug info at M.)

Picking the JVM state is harder than it looks, when you are using the GraphKit after the parsing phase is finished. It is possible that the JVM for M was never in fact recorded by the parser; it was simply constructed and then immediately replaced by the next parsed state.

— John


More information about the hotspot-compiler-dev mailing list