On Mon, 15 Jun 2026 11:43:04 GMT, Marc Chevalier <[email protected]> wrote:

> The whole problem is there:
> 
> https://github.com/openjdk/valhalla/blob/1ca1c8d9301215d43eb0d012cdc42ddbe7549d14/src/hotspot/share/opto/vector.cpp#L204-L210
> 
> We are rebuilding the top of the bytecode stack before the call by pushing 
> the arguments. This will end up as the debug inputs for the allocation in 
> `kit.box_vector` (throught the chain `GraphKit::box_vector` -> 
> `GraphKit::set_edges_for_java_call` -> `GraphKit::add_safepoint_edges`). 
> Having the wrong inputs on the allocation means that if it deopts, the 
> bytecode state will be restored wrong.
> 
> In a case such as in the test, one of the local is scalarized and takes only 
> one slot on the expression stack (in the bytecode). Meanwhile, for C2, the 
> value is passed scalarized to the call, so we have inputs for the buffer, the 
> null marker, and each field. The current implementation has two issues, the 
> first one is that it iterates with the size of `domain_sig()`, that is the 
> signature as it appears in the Java code. In the example, that will be 
> `MyValue` and `IntVector`, thus a length of 2. But the inputs of `call` will 
> reflect the signature `domain_cc()`, that is with the scalarized calling 
> convention, which will be in the example: oop buffer for `MyValue`, null 
> marker, the integer field, and `IntVector` (length = 4). So, the current code 
> fails to gather all locals entirely. But replacing `domain_sig` with 
> `domain_cc` isn't enough either. If we do that, we do collect everything, but 
> they end up as independent values on the bytecode expression stack. This is 
> visible in the opto
 assembly:
> 
> 19b     call,static  wrapper for: new_array_blob (C2 runtime)
>         # ...::test @ bci:54 (line 45) L[0]=RBP L[1]=rsp + #4 L[2]=#ScObj0 
> L[3]=#ScObj1 L[4]=#ScObj2 L[5]=#ScObj3 STK[0]=#null STK[1]=#1 STK[2]=rsp + #4 
> STK[3]=#ScObj3
>         # ScObj0 ...$MyValue={ [null marker :-1]=#1 [a :0]=rsp + #4 }
>         # ScObj1 jdk/incubator/vector/IntVector128={ [payload :0]=rsp + #32 }
>         # ScObj2 jdk/incubator/vector/IntVector128={ [payload :0]=rsp + #16 }
>         # ScObj3 jdk/incubator/vector/IntVector128={ [payload :0]=rsp + #48 }
>         # OopMap {off=416/0x1a0}
> 
> Here, it looks like the stack should have 4 slots (instead of 2), and we can 
> recognize the slots 0, 1 and 2 that forms actually the value `myVal`. But as 
> a result, after deoptimization, the interpreter is given a state that is not 
> correct.
> 
> So, on top of actually iterating over all the inputs of `call` we also need 
> to group them inside an `InlineType` (that will be scala...

This pull request has now been integrated.

Changeset: ed61dc28
Author:    Marc Chevalier <[email protected]>
URL:       
https://git.openjdk.org/valhalla/commit/ed61dc2826dfeb8b5289cf16fc61bf045fc5dcb5
Stats:     95 lines in 2 files changed: 93 ins; 0 del; 2 mod

8385886: [lworld] C2 VectorAPI/value type: bad deopt state leads to wrong result

Reviewed-by: qamai, dlong

-------------

PR: https://git.openjdk.org/valhalla/pull/2547

Reply via email to