Skip to content
Advertisement

Java bytecode – Why is offset being skipped?

I have this very simple class

public class TestImpl2 {
    public TestImpl2() {
    }

    public double run(double param) {
        double d = 7.0D;
        double k = 4.0D;
        if (param < k) {
            System.out.println(d);
        }

        return 0.0D;
    }
}

That i compiled with javac and then decompiled with javap to see its bytecode.

     0: ldc2_w        #14                 // double 7.0d
     3: dstore_3
     4: ldc2_w        #16                 // double 4.0d
     7: dstore        5
     9: dload_1
    10: dload         5
    12: dcmpg
    13: ifge          23
    16: getstatic     #23                 // Field java/lang/System.out:Ljava/io/PrintStream;
    19: dload_3
    20: invokevirtual #29                 // Method java/io/PrintStream.println:(D)V
    23: dconst_0
    24: dreturn

Lets check offsets

0 – is reserved for “this” reference

1 – is the method parameter

2 – skipped ?

3 – variable “d”

4 – skipped ?

5 – variable “k”

Why were offsets 2 and 4 skipped? Is it because method param, d and k are doubles or is it something completly else?

Advertisement

Answer

According to the JVM spec (emphasis mine):

Local variables are addressed by indexing. The index of the first local variable is zero. An integer is considered to be an index into the local variable array if and only if that integer is between zero and one less than the size of the local variable array.

A value of type long or type double occupies two consecutive local variables. Such a value may only be addressed using the lesser index. For example, a value of type double stored in the local variable array at index n actually occupies the local variables with indices n and n+1; however, the local variable at index n+1 cannot be loaded from.

It is not that indices 2 and 4 are not used. It’s just that param and d are doubles and they occupy 2 spaces each.

Advertisement