JDK-8321039 : [lworld] Substitutability code must recognize new annotations
  • Type: Enhancement
  • Component: core-libs
  • Affected Version: repo-valhalla
  • Priority: P3
  • Status: In Progress
  • Resolution: Unresolved
  • Submitted: 2023-11-29
  • Updated: 2023-12-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
repo-valhallaUnresolved
Related Reports
Relates :  
Description
The substitutability code currently doesn't recognize the @NullRestricted annotation added by JDK-8320437, which causes some failures when comparing some annotated value classes:

import jdk.internal.misc.VM;
import jdk.internal.vm.annotation.ImplicitlyConstructible;
import jdk.internal.vm.annotation.LooselyConsistentValue;
import jdk.internal.vm.annotation.NullRestricted;

public class Test {

    @ImplicitlyConstructible
    @LooselyConsistentValue
    static value class MyValueEmpty {

    }

    @ImplicitlyConstructible
    @LooselyConsistentValue
    static value class EmptyContainer {
        @NullRestricted
        MyValueEmpty empty = new MyValueEmpty();
    }

    public static void main(String[] args) {
        if (new EmptyContainer() != EmptyContainer.default) {
            throw new RuntimeException("Failed");
        }
    }
}

This test fails when run with -XX:InlineFieldMaxFlatSize=0.

The newly created EmptyContainer has been created by a constructor which explicitly initialized the empty field with a reference to an instance of MyEmptyValue. The EmptyContainer.default value is the default value created by the VM, and the VM is lazy on null-free non-flat fields. The whole default value is initialized will zeroes, which is equivalent to initializing non-flat fields with a null reference, but on read, the VM substitute this null reference with the default value of the field's type. The Java code used for the substitutability test, called from if_acmpeq when two values of the same type are compared, is aware of the VM lazy initialization of null-free non-flat fields and usually recognizes this situation and perform the same substitution. The problem here is that the substitutability code doesn't recognize the field as a non-free non-flat field, because it isn't aware that the @NullRestricited annotation has the same effect as a Q-descriptor in the field signature. So, the substitutability code performs a simple comparison between the reference from the initialized field and the null reference of the default value, finds them different and returns a value indicating that the two arguments are different.

Comments
This could be considered as a subtask of JDK-8317767 as it depends on the ability to determine if a field is null-restricted. Field instances are created by VM and so it's straight-forward to carry the null-restricted bit. The substitutability test will need to handle the case when a field of a null-restricted value type whose value is the null reference, it will use the zero instance for comparison instead.
01-12-2023