-
Enhancement
-
Resolution: Fixed
-
P3
-
repo-valhalla
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 null-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.
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 null-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.
- duplicates
-
JDK-8317150 [lworld] valhalla/valuetypes/ObjectMethods.java fails after jdk-22+9
-
- Closed
-
-
JDK-8317151 [lworld] valhalla/valuetypes/SubstitutabilityTest.java fails after merging jdk-22+9
-
- Closed
-
- relates to
-
JDK-8317767 Standard library implementation of null-restricted value class types
-
- Open
-