Question

I am trying to figure out the bytecode size of a method because I want to be sure that it will be small enough to be inlined by compiler optimizations.

I saw that the default max size for inlining methods is 35, so if the method is larger than that I will revise the code or break it into multiple methods.

I have a method that generates the bytecode below (disassembled via the ASM Bytecode Outline plugin for IntelliJ IDEA).

How can I tell the bytecode size of that method? the LINENUMBERs seem to reference the line numbers of the original source code.

public static mergeNativeArrays([Ljava/lang/Object;[Ljava/lang/Object;IZ)[Ljava/lang/Object;
 L0
  LINENUMBER 865 L0
  ALOAD 0
  ASTORE 4
 L1
  LINENUMBER 867 L1
  ILOAD 2
  IFGE L2
 L3
  LINENUMBER 868 L3
  ALOAD 0
  ARRAYLENGTH
  ISTORE 2
 L2
  LINENUMBER 870 L2
 FRAME APPEND [[Ljava/lang/Object;]
  ILOAD 2
  ALOAD 1
  ARRAYLENGTH
  IADD
  ISTORE 5
 L4
  LINENUMBER 872 L4
  ALOAD 4
  ARRAYLENGTH
  ILOAD 5
  IF_ICMPGE L5
 L6
  LINENUMBER 874 L6
  ILOAD 3
  IFEQ L7
 L8
  LINENUMBER 875 L8
  ILOAD 5
  INVOKESTATIC railo/commons/math/MathUtil.nextPowerOf2 (I)I
  ISTORE 5
 L7
  LINENUMBER 877 L7
 FRAME APPEND [I]
  ILOAD 5
  ANEWARRAY java/lang/Object
  ASTORE 4
 L9
  LINENUMBER 878 L9
  ALOAD 0
  ICONST_0
  ALOAD 4
  ICONST_0
  ALOAD 0
  ARRAYLENGTH
  INVOKESTATIC java/lang/System.arraycopy (Ljava/lang/Object;ILjava/lang/Object;II)V
 L5
  LINENUMBER 881 L5
 FRAME SAME
  ALOAD 1
  ICONST_0
  ALOAD 4
  ILOAD 2
  ALOAD 1
  ARRAYLENGTH
  INVOKESTATIC java/lang/System.arraycopy (Ljava/lang/Object;ILjava/lang/Object;II)V
 L10
  LINENUMBER 883 L10
  ALOAD 4
  ARETURN
 L11
  LOCALVARIABLE dst [Ljava/lang/Object; L0 L11 0
  LOCALVARIABLE src [Ljava/lang/Object; L0 L11 1
  LOCALVARIABLE dstPosition I L0 L11 2
  LOCALVARIABLE doPowerOf2 Z L0 L11 3
  LOCALVARIABLE result [Ljava/lang/Object; L1 L11 4
  LOCALVARIABLE newSize I L4 L11 5
  MAXSTACK = 5
  MAXLOCALS = 6
Was it helpful?

Solution

How can I tell the bytecode size of that method?

One way is to just add them up :-)

Each bytecode instruction consists of 1 byte for the primary instruction plus a fixed number of operand bytes.


A more practical way is to dump the classfile containing the bytecodes using javap -c. The output includes byte offsets for each instruction.

Reference: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html


1) I can add ALOAD 0 ASTORE 4 as 4 bytes, but what do I do with with ARRAYLENGTH or INVOKESTATIC method-name?

The instructions are listed in Section 6.5 of the JVM spec - http://docs.oracle.com/javase/specs/jvms/se7/html/index.html

  1. Scroll down to the relevant part of the index.
  2. Click on the link for the instruction.
  3. Read the "format" and "description" to figure out how many bytes are used.

Following this procedure, I deduced that ARRAYLENGTH is 1 byte, and INVOKESTATIC is 3 bytes.

2) I tried to use javap but for some reason I get class not found (it's inside a jar and I passed -classpath filename.jar to javap but it didn't work).

Read the javap manual entry again. It does work if you use it correctly. (Perhaps you didn't supply the fully-qualified classname in the correct format.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top