On Fri, 29 May 2026 09:08:27 GMT, Maurizio Cimadamore <[email protected]> 
wrote:

> This PR cleans the handling of unset strict fields which is needed for 
> stackmap generation.
> In the current impl, this is done with UnsetFieldsInfo which is prepared by 
> Flow, and then propagated to Gen/Code.
> The problem with this approach is that we introduce unnecessary coupling, as 
> we need to keep track where, at the AST level, an assignment to a strict 
> uninit variable takes place.
> This leads to issues as the AST-oriented view is too high-level for the kind 
> of manipulation that Code needs.
> By modelling unset fields as a bitset in Code.State (same as what we do to 
> keep track of local variable ranges), state merges are dealt with more 
> naturally and succinctly.
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/legal/ai).

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java line 235:

> 233: 
> 234:     void initUnsetStrictFields(ClassSymbol csym) {
> 235:         int strictFieldOffset = 0;

Here we collect all strict instance fields in the class scope. These symbols 
are normally returned in reversed order, so using `prepend` restores natural 
source order.

Also, we override `adr` -- which is ok, because we only need that for local 
variables (and strict fields are... fields).

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java line 1070:

> 1068:                     field.owner == meth.owner &&
> 1069:                     state.peek().hasTag(UNINITIALIZED_THIS)) {
> 1070:                 state.unsetStrict.excl(field.adr);

This is where all the magic happens -- if we see a putfield targeting a strict 
instance field of this class and the "receiver" is uninitialized, we transition 
that field to "init".

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java line 1849:

> 1847:         State join(State other) {
> 1848:             defined.andSet(other.defined);
> 1849:             unsetStrict.orSet(other.unsetStrict);

This is important: unset field in a merged frame is obtaining by OR-ing the 
unset state of the parent frames.

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

PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2487#discussion_r3323332493
PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2487#discussion_r3323339393
PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2487#discussion_r3323345750

Reply via email to