Home > Back-end >  Why jump instead of return in Java bytecode?
Why jump instead of return in Java bytecode?

Time:11-03

Background

I compiled the following method:

public static final boolean equalTo(final int x, final int y) {
    return x == y;
}

And with javap could see that the following bytecode was produced for it:

  public static final boolean equalTo(int, int);                                                                                                                                                                 
    descriptor: (II)Z                                                                                                                                                                                            
    flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL                                                                                                                                                            
    Code:                                                                                                                                                                                                        
      stack=2, locals=2, args_size=2                                                                                                                                                                             
         0: iload_0                                                                                                                                                                                              
         1: iload_1                                                                                                                                                                                              
         2: if_icmpne     9                                                                                                                                                                                      
         5: iconst_1                                                                                                                                                                                             
         6: goto          10                                                                                                                                                                                     
         9: iconst_0                                                                                                                                                                                             
        10: ireturn                                                                                                                                                                                              
      LineNumberTable:                                                                                                                                                                                           
        line 72: 0                                                                                                                                                                                               
      StackMapTable: number_of_entries = 2                                                                                                                                                                       
        frame_type = 9 /* same */                                                                                                                                                                                
        frame_type = 64 /* same_locals_1_stack_item */                                                                                                                                                           
          stack = [ int ]                                                    

I wrote ASM that would create the same bytecode, and also created another version that behaved the same by changing the goto 10 to an ireturn. It's negligible, but this also reduces the size of the StackMapTable since it eliminates a jump.

Question

I know "it's only bytecode" and not indicative of what the machine will do, but why does the compiler emit goto 10 when it could simply emit ireturn?

CodePudding user response:

Frontend compilers generate code using simple patterns, and they rely on optimization passes to clean things up. At the point that the x == y expression is generated, the compiler doesn't "know" that the very next thing is a return statement. It could potentially check this, but that extra step can be handled just as easily with some sort of peephole optimizer.

The benefit of a peephole optimizer is that it can perform cascading optimizations, that is, the result of one optimization can feed into the next one. The code that generated the x == y expression doesn't really have any way of performing anything more than one optimization step without adding more complexity.

The java compiler used to have an optimization feature, but this was ditched in favor of HotSpot, which can perform even more powerful optimizations. Performing optimizations in the java compiler would slow it down and not really improve things all that much.

  • Related