Reputation: 23493
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
Upvotes: 9
Views: 3821
Reputation: 718768
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
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.)
Upvotes: 8