cs24-22fa javap

Introduction to Computing Systems (Fall 2022)

Java provides a handy tool javap that prints the contents of a .class file. When used with the -v flag, it shows the Java bytecode instructions in each method. For the jvm project, it can be run using javap -cp tests -v TEST_NAME. For example:

$ javap -cp tests -v OnePlusTwo
public class OnePlusTwo
  minor version: 3
  major version: 45
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #6                          // OnePlusTwo
  super_class: #9                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 1, attributes: 1
Constant pool:
   #1 = Utf8               java/lang/Object
   #2 = Utf8               SourceFile
   #3 = Utf8               OnePlusTwo
   #4 = Utf8               main
   #5 = Utf8               Code
   #6 = Class              #3             // OnePlusTwo
   #7 = Utf8               ([Ljava/lang/String;)V
   #8 = Utf8               OnePlusTwo.j
   #9 = Class              #1             // java/lang/Object
{
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=1, args_size=1
         0: bipush        1
         2: bipush        2
         4: iadd
         5: return
}
SourceFile: "OnePlusTwo.j"

Note that much of this information is extraneous: mainly the Constant pool and Code sections will be useful! The number to the left of each instruction indicates its offset in the bytecode (so you can see that bipush is a 2-byte instruction). The instructions are listed using the same mnemonics as in the spec. Any arguments to the instruction (e.g. 1 or 2 above) are listed after the instruction mnemonic.

Here is a longer method (Jumps.catalan()) that shows a few more instructions:

public static int catalan(int);
  descriptor: (I)I
  flags: (0x0009) ACC_PUBLIC, ACC_STATIC
  Code:
    stack=3, locals=3, args_size=1
       0: iload_0
       1: ifne          6
       4: iconst_1
       5: ireturn
       6: iconst_0
       7: istore_1
       8: iconst_0
       9: istore_2
      10: iload_1
      11: iload_2
      12: iinc          2, 1
      15: invokestatic  #7                  // Method catalan:(I)I
      18: iinc          0, -1
      21: iload_0
      22: invokestatic  #7                  // Method catalan:(I)I
      25: imul
      26: iadd
      27: istore_1
      28: iload_0
      29: ifgt          10
      32: iload_1
      33: ireturn

Note that the jump instructions are shown with absolute offsets. For example, ifgt 10 means “jump to instruction 10 if the value popped from the stack is greater than 0”.