compiling Enum.ordinal() into constant inside a method

Vladimir Kozlov vladimir.kozlov at oracle.com
Sat Feb 28 01:29:38 UTC 2015


C2 doesn't treat final fields as constants:

  private final int ordinal;

Only (@Stable) and special final cases:

       // Treat final non-static fields of trusted classes (classes in
       // java.lang.invoke and sun.invoke packages and subpackages) as
       // compile time constants.

Regards,
Vladimir

On 2/27/15 10:08 AM, Vitaly Davidovich wrote:
> Hi guys,
>
> Suppose we have an enum like this:
>
> enum E { ONE, TWO }
>
> Then we have a method like so:
>
> static E valueOf(int ordinal) {
>     if (ordinal == E.ONE.ordinal()) return E.ONE;
>     if (ordinal == E.TWO.ordinal()) return E.TWO;
>     throw new <some_exception>; // this path never taken
> }
>
> On 7u60 (sorry, can't easily test on a later version now), the compiled
> code (C2) is actually loading the ordinal field for both comparisons.
> Of course doing the following:
>
> static final int ONE = E.ONE.ordinal();
> static final int TWO = E.TWO.ordinal();
>
> static E valueOf(int ordinal) {
>     if (ordinal == ONE) return E.ONE;
>     if (ordinal == TWO) return E.TWO;
>     throw new <some_exception>; // this path never taken
> }
>
> uses constant comparisons (well, the zero case is just a test, but 1
> uses cmp).
>
> Is there a good reason why the first version of the method cannot be
> compiled into the second one? Apologies if this is actually the case on
> later hotspot versions, in which case I'd be happy to hear that.
>
> Thanks


More information about the hotspot-compiler-dev mailing list