Нахождение размера байт-кода метода
Я пытаюсь выяснить размер байт-кода метода, потому что я хочу быть уверен, что он будет достаточно маленьким, чтобы его можно было оптимизировать при оптимизации компилятора.
Я видел, что максимальный размер по умолчанию для методов встраивания равен 35, поэтому, если метод больше этого, я буду пересматривать код или разбивать его на несколько методов.
У меня есть метод, который генерирует байт-код ниже (разобран через плагин ASM Bytecode Outline для IntelliJ IDEA).
Как я могу определить размер байт-кода этого метода? LINENUMBERs, кажется, ссылаются на номера строк исходного исходного кода.
ТИА
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
1 ответ
Как я могу определить размер байт-кода этого метода?
Один из способов - просто сложить их:-)
Каждая инструкция байт-кода состоит из 1 байта для основной инструкции плюс фиксированное количество байтов операнда.
Более практичный способ - сбросить файл класса, содержащий байт-коды, используя javap -c
, Вывод включает смещения байтов для каждой инструкции.
Ссылка: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html
1) Я могу добавить ALOAD 0 ASTORE 4 как 4 байта, но что мне делать с ARRAYLENGTH или INVOKESTATIC-методом-именем?
Инструкции перечислены в разделе 6.5 спецификации JVM - http://docs.oracle.com/javase/specs/jvms/se7/html/index.html
- Прокрутите вниз до соответствующей части указателя.
- Нажмите на ссылку для инструкции.
- Прочитайте "формат" и "описание", чтобы выяснить, сколько байтов используется.
Следуя этой процедуре, я сделал вывод, что ARRAYLENGTH составляет 1 байт, а INVOKESTATIC - 3 байта.
2) Я пытался использовать javap, но по какой-то причине я не нашел класс (он находится внутри jar, и я передал -classpath filename.jar в javap, но он не работал).
Прочитайте javap
ручной ввод снова. Это работает, если вы используете его правильно. (Возможно, вы не указали полное имя класса в правильном формате.)