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
Each bytecode is composed of one byte that represents the opcode, along with zero or more bytes for operands. Of the 256 possible byte-long opcodes, as of 2015, 202 are in use (~79%), 51 are reserved for future use (~20%), and 3 instructions (~1%) are permanently reserved for JVM implementations to use.
Show bytecode for compiled files By default, the IDE shows you decompiled code in compiled files. If necessary, you can open the bytecode viewer for any compiled class. Open a compiled file in the editor and select View | Show Bytecode from the main menu.
The bytecodes streams are stored in the method area of the JVM. The bytecodes for a method are executed when that method is invoked during the course of running the program.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With