code generation of a switch on an enum

John Rose john.r.rose at oracle.com
Thu Sep 11 02:50:54 UTC 2014


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



More information about the hotspot-compiler-dev mailing list