RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v25]

Per Minborg pminborg at openjdk.org
Fri Nov 14 13:35:17 UTC 2025


On Tue, 11 Nov 2025 16:48:58 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:

>> I've added two new benchmarks:
>> 
>> 
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_42 = LazyConstant.of(() -> Optional.of(42));
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_42_2 = LazyConstant.of(() -> Optional.of(42));
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_EMPTY = LazyConstant.of(Optional::empty);
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_EMPTY2 = LazyConstant.of(Optional::empty);
>>     
>>     ...
>>     
>>         @Benchmark
>>     public int staticOptional42() {
>>         return OPTIONAL_42.get().orElseThrow() + OPTIONAL_42_2.get().orElseThrow();
>>     }
>> 
>>     @Benchmark
>>     public boolean staticOptionalEmpty() {
>>         return OPTIONAL_EMPTY.get().isEmpty() ^ OPTIONAL_EMPTY2.get().isEmpty();
>>     }
>> 
>>     
>> 
>> 
>> Which gives:
>> 
>> 
>> Benchmark                              Mode  Cnt  Score   Error  Units
>> StableValueBenchmark.staticOptional42  avgt   10  0.354 ± 0.045  ns/op
>> 
>> Benchmark                                 Mode  Cnt  Score   Error  Units
>> StableValueBenchmark.staticOptionalEmpty  avgt   10  0.370 ± 0.030  ns/op
>> 
>> 
>> So, both `Optional` variants appears to support constant folding.
>
> I don't think we can drawn that conclusion just based on the speed. For the non-constant folded cases, this would be 2 loads and an xor.
> 
> I don't see how C2 would be allowed to constant fold the loads if the value is `null`, since that's explicitly forbidden by `@Stable` (and there's no easy way around that AFAIK, since the JIT thread may see a partially initialized object, so it conservatively ignores default values).

Yes. I think you are right @JornVernee. I've explored several ways to fix this and the simplest one might be to have a sentinel value instead of `null` to flag emptiness. Splitting the class into a bimorphic implementation would not be good for `value` classes (at least not for now), even though the C2 might otherwise be able to optimize the two variants.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2527523848


More information about the nio-dev mailing list