Hi Chen, just searching GitHub it seems there are 2600 results for
Class#getEnumConstants()[0], from looking at them it's mostly used in a
fallback scenario in most cases when they only have the Class. So I
wouldn't be surprised if most of these callsites would never be able to be
resolved, this was meant to be an example that's easy to make an IR test &
micro benchmark for.

Class#enumConstants are also used in getting the universe of EnumMap,
EnumSet, So call sites like EnumSet.noneOf(Class), and EnumMap(Class) would
also benefit from such a change as it may be able to fold the volatile
read. (untested)

In defense to using @Stable over LazyConstant is there would be a
capturing lambda plus an LazyConstant allocated for every class even if
it's not an Enum, then if you wanted to make LazyConstant itself lazy it
would also require a @Stable to be able to fold. This seems like an
antipattern. Also this kind of goes against the idea behind caching
Class#enumConstants here as it is currently null if it's never used. As for
the implementation I have in mind would also likely place the
Unsafe#compareAndExchangeReference in the existing Class.Atomic as to still
allow this being used early in the startup process similar to LazyConstant.

Please let me know if you have any additional questions.

Cheers,
Ryan Hallock

On Thu, Feb 12, 2026 at 11:46 PM Chen Liang <[email protected]> wrote:

> Hi Ryan, is there a use case where people call getEnumConstants() and
> access a fixed index of array element?
>
> This is so far the only use case I can think of that would be negatively
> impacted by the lack of constant folding for this method.
>
> In addition, I do not recommend adding more @Stable - we should consider
> better representations like LazyConstant.
>
> Regards
> ------------------------------
> *From:* core-libs-dev <[email protected]> on behalf of Ryan
> Hallock <[email protected]>
> *Sent:* Thursday, February 12, 2026 3:45 PM
> *To:* [email protected] <[email protected]>
> *Subject:* Add @Stable to Class#enumConstants.
>
> Hello, I am new to OpenJDK development and I want to propose changes to
> Class#enumConstants from
> Class#getEnumConstants()/Class#getSharedEnumConstants().
>
> Currently consider the following example:
> ```java
> enum E {
>     A, B, C
> }
> E[] values = E.values();
> E[] constants = E.class.getEnumConstants();
> assert Arrays.equals(values, constants);
> ```
> These methods provide an equal array of values, but they are treated
> differently. This is because the _constants_ stored by Class#enumConstants
> are non final and declared volatile. So C2 can't trust this call. Consider
> if I only wanted to access the value from an offset from these arrays.
> ```java
> E value = values[0];
> E constant = constants[0];
> assert value == constant;
> ```
> _constant_ would never be folded but _value_ would be.
>
> So I propose the addition of @Stable annotation added to
> Class#enumConstants so _constant_ can be folded by C2. This is not a
> trivial change as it requires changing the data race to abide by @Stable.
> Could I be sponsored for this change (JBS issue as well)?
>
> A future proposal would be adding @Stable to Class#enumConstantDirectory,
> though that can be a seperate enhancement as that might require changing of
> the data structure to allow folding. Let me know if it should be combined
> as the Stable annotation itself would be implemented in a similar way for
> both.
>
> Thanks,
> Ryan Hallock
>
>

Reply via email to