code generation of a switch on an enum

Vitaly Davidovich vitalyd at gmail.com
Thu Sep 11 03:02:40 UTC 2014


Thanks John!

Besides not special casing the FOUR constant here (which the bug report
addresses), why is a lookup switch used and not a table switch? The numeric
range is dense with no holes at all, so even if FOUR isn't special cased,
it's surprising to see a lookup instead of a switch.

Sent from my phone
On Sep 10, 2014 10:50 PM, "John Rose" <john.r.rose at oracle.com> wrote:

> So I went into JBS to find the bug for this long-known problem, and came
> up empty.
> Thanks for reporting it!  I filed this:
>   https://bugs.openjdk.java.net/browse/JDK-8058192
>
> — John
>
> On Sep 10, 2014, at 3:54 PM, Vitaly Davidovich <vitalyd at gmail.com> wrote:
>
> > Hi guys,
> >
> > Looking at generated asm (x86-64 SandyBridge, 1.7u60) for a switch
> statement on an enum from C2 compiler, I'm wondering whether there's some
> missing profile information that could be incorporated into the generated
> code.
> >
> > private enum E {
> >       ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE
> >     }
> >
> > private static int getInt(E e) {
> >       switch (e) {
> >       case ZERO: return 0;
> >       case ONE: return 1;
> >       case TWO: return 2;
> >       case THREE: return 3;
> >       case FOUR: return 4;
> >       case FIVE: return 5;
> >       case SIX: return 6;
> >       case SEVEN: return 7;
> >       case EIGHT: return 8;
> >       case NINE: return 9;
> >
> >       default: throw new Error();
> >       }
> >     }
> >
> > public void foo() {
> >       int sum = 0;
> >       for (int i = 0; i < 100000; ++i) {
> >           sum += getInt(E.FOUR);
> >       }
> >       System.out.println(sum);
> >     }
> >
> > The generated code for getInt() appears to proceed through a binary
> search of the enum ordinal range, trying to match the incoming argument.
> But, as can be seen above, the incoming argument is always E.FOUR.  I tried
> to restrict E to have only 4 members, but the strategy used by the JIT
> didn't change.  Why isn't it doing a quick test against FOUR before
> proceeding with the search through the value range?
> >
> > Also, what's the reason this isn't generating a direct lookup into a
> switch table? If I change getInt() above to do the ordinal switching myself:
> >
> > switch (e.ordinal()) {
> >       case 0: return 0;
> >       case 1: return 1;
> >       case 2: return 2;
> >       case 3: return 3;
> >       case 4: return 4;
> >       case 5: return 5;
> >       case 6: return 6;
> >       case 7: return 7;
> >       case 8: return 8;
> >       case 9: return 9;
> >
> >       default: throw new Error();
> >
> > It still generates the same type of code.  For comparison, gcc 4.9 and
> clang 3.4.1 generate a lookup into a switch table after checking that the
> argument isn't going to go into the default case.
> >
> > I can paste the generated asm if that helps, but it should be easy to
> reproduce given the above code.
> >
> > Thanks
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20140910/0cff19c1/attachment.html>


More information about the hotspot-compiler-dev mailing list