Search code examples
javaconstantsbytecodeoperand

Accessing values from Constant Pool Java Bytecode


I have the following code:

    public static void f(){
        double i = 0.0;
        for(i = 0.0; i<100.0; i++){}   
    }

which translates to the following bytecode:

public static void f();
Code:
   0: dconst_0
   1: dstore_0
   2: dconst_0
   3: dstore_0
   4: dload_0
   5: ldc2_w        #2                  // double 100.0d
   8: dcmpg
   9: ifge          19
  12: dload_0
  13: dconst_1
  14: dadd
  15: dstore_0
  16: goto          4
  19: return

I'm confused about the line containing the comment //double 100.0d

I sort of understand what ldc2_w does. It grabs the appropriate constant from the constant pool. And the constant pool contains a list of defined constants after parsing the Java code, right?

But what is the purpose of #2? How would one know what number should go here? On an online tutorial I saw someone use #4 instead?

What does this operand mean?


Solution

  • But what is the purpose of #2? How would one know what number should go here? On an online tutorial I saw someone use #4 instead?

    Normally you don't. If you're writing bytecode assembly, you typically rely on the assembler to fill in the constant pool for you.

    For example, if you write

    ldc2_w 100.0
    

    In Jasmin or Krakatau, the assembler will automatically create a constant pool entry for 100.0 and then fill in the appropriate index. It could be 2, it could be 4, it could be 50000. It depends on what else is in the constant pool, but you normally don't care about that.

    The Krakatau assembler allows you to also specify constant pool entries manually. So if you wanted to make sure that your double was at position 2, you could do

    .const [2] = Double 100.0
    ldc2_w [2]
    

    However, there is almost never any reason to do so. This is only useful if you care about the exact binary layout of the classfile.

    As for why you're seeing the #2, that's because that's just the way Javap is. It's meant for a quick inspection of bytecode. If you use a different tool, you'll get different results. For example, the Krakatau disassembler would just print out ldc2_w 100.0 unless you specify roundtrip mode.