code generation of a switch on an enum

Vitaly Davidovich vitalyd at
Wed Sep 10 22:54:50 UTC 2014

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

private enum E {

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);

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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the hotspot-compiler-dev mailing list