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

Jorn Vernee jvernee at openjdk.org
Wed Nov 12 16:39:59 UTC 2025


On Mon, 13 Oct 2025 11:25:04 GMT, Per Minborg <pminborg at openjdk.org> wrote:

>> Usually a null sentinel is used when null indicates something different. I think maybe to allow folding the empty case, we should probably add a new annotation or a new element-value to indicate this status and properly handle it in C1/C2 (similar to the field trusting in ciField)
>
> 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).

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

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


More information about the core-libs-dev mailing list