Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the Bytecode Size of a Java Method

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
like image 432
isapir Avatar asked Jan 25 '14 23:01

isapir


People also ask

What is the size of bytecode in Java?

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.

How do I find my byte code?

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.

Where is byte code stored Java?

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.


1 Answers

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.)

like image 159
Stephen C Avatar answered Sep 23 '22 08:09

Stephen C