<p dir="ltr">Thanks John!</p>
<p dir="ltr">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.</p>
<p dir="ltr">Sent from my phone</p>
<div class="gmail_quote">On Sep 10, 2014 10:50 PM, "John Rose" <<a href="mailto:john.r.rose@oracle.com">john.r.rose@oracle.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">So I went into JBS to find the bug for this long-known problem, and came up empty.<br>
Thanks for reporting it!  I filed this:<br>
  <a href="https://bugs.openjdk.java.net/browse/JDK-8058192" target="_blank">https://bugs.openjdk.java.net/browse/JDK-8058192</a><br>
<br>
— John<br>
<br>
On Sep 10, 2014, at 3:54 PM, Vitaly Davidovich <<a href="mailto:vitalyd@gmail.com">vitalyd@gmail.com</a>> wrote:<br>
<br>
> Hi guys,<br>
><br>
> 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.<br>
><br>
> private enum E {<br>
>       ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE<br>
>     }<br>
><br>
> private static int getInt(E e) {<br>
>       switch (e) {<br>
>       case ZERO: return 0;<br>
>       case ONE: return 1;<br>
>       case TWO: return 2;<br>
>       case THREE: return 3;<br>
>       case FOUR: return 4;<br>
>       case FIVE: return 5;<br>
>       case SIX: return 6;<br>
>       case SEVEN: return 7;<br>
>       case EIGHT: return 8;<br>
>       case NINE: return 9;<br>
><br>
>       default: throw new Error();<br>
>       }<br>
>     }<br>
><br>
> public void foo() {<br>
>       int sum = 0;<br>
>       for (int i = 0; i < 100000; ++i) {<br>
>           sum += getInt(E.FOUR);<br>
>       }<br>
>       System.out.println(sum);<br>
>     }<br>
><br>
> 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?<br>
><br>
> 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:<br>
><br>
> switch (e.ordinal()) {<br>
>       case 0: return 0;<br>
>       case 1: return 1;<br>
>       case 2: return 2;<br>
>       case 3: return 3;<br>
>       case 4: return 4;<br>
>       case 5: return 5;<br>
>       case 6: return 6;<br>
>       case 7: return 7;<br>
>       case 8: return 8;<br>
>       case 9: return 9;<br>
><br>
>       default: throw new Error();<br>
><br>
> 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.<br>
><br>
> I can paste the generated asm if that helps, but it should be easy to reproduce given the above code.<br>
><br>
> Thanks<br>
<br>
</blockquote></div>