SlideShare a Scribd company logo
Основы байт-кода Java
План

Что такое байт-код?
Основные понятия
Соответствие между Java и байт-кодом
Библиотека ASM
JDK 5-7
Байт-код

Промежуточное
представление между Java и
машинным кодом
Исходный код переводится в
байт-код максимально
близко либо выражается его
средствами
Большинство ограничений
Java распространяются на
байт-код.


                         Source: http://viralpatel.net/blogs/java-virtual-machine-an-inside-story/
Что можно делать с байт-кодом?

Читать
– javap
– Анализ классов
– Анализ и модификация стороннего кода
Создавать
– Генерация классов на лету
– Компиляция
Изменять
– AOP
– Инструментация
– Профилирование
Понимать
– Франкенбилды
Почему он нужен редко?

Декомпиляторы
– Jad
Существующие средства AOP
– AspectJ
java.lang.reflect.Proxy
Средства для работы с байт-кодом

ASM
CGLIB
BCEL
SERP
Javassist
Jasmin
Jamaica
План

Что такое байт-код?
Основные понятия
Соответствие между Java и байт-кодом
Библиотека ASM
JDK 5-7
Структура класса

Все компилируется в .class
– Классы
– Интерфейсы
    • <clinit>
– Аннотации
    • java.lang.annotation.Annotation
– Перечисления
    • java.lang.Enum




                             Source: http://viralpatel.net/blogs/tutorial-java-class-file-format-revealed/
Стек и регистры

Регистры используются для локальных переменных
Операции производятся со стеком, например:
– public float sum(int a, int b) { return a + b; } становится
    •   iload_1 // положить в стек значение параметра a
    •   iload_2 // положить в стек значение параметра b
    •   Iadd // сложить два верхних элемента стека, результат в стек
    •   I2f // сконвертировать верхний элемент стека из int в float
    •   freturn // вернуть верхний элемент стека
В стеке и регистрах хранятся 32-битные значения
long и double занимают две ячейки
Сигнатуры

Z = boolean, C, B, S, I, J = long, F, D
Массив: [[Z = boolean[][]
Объект: Ljava/lang/Integer; = java.lang.Integer
Метод: (II)V = void(int, int)
Пример использования:
– private Object x = new StringBuffer(); становится
    •   aload_0
    •   invokespecial java/lang/Object."<init>":()V
    •   aload_0
    •   new java/lang/StringBuffer
    •   dup
    •   invokespecial java/lang/StringBuffer."<init>":()V
    •   putfield x:Ljava/lang/Object;
    •   return
Опкоды

Соглашения
– Приставки
    • b, c, s, i, l, f, d
    • a = reference
– iload_0 = iload 0
Работа со стеком
– Занесение значения регистра в стек
    • aload, dload, fload, iload, lload
– Перенос верхнего значения из стека в регистр
    • astore, dstore, fstore, istore, lstore
– Запись константы в стек
    • aconst_null, dconst_{0,1}, fconst_{0,1,2}, iconst_{m1,0,1,2,3,4,5}, lco
      nst_{0,1}, ldc, ldc2, bipush, sipush
– Изменение вершины стека
    • pop, pop2, dup, dup2, dup2_x1, dup2_x2, dup_x1, dup_x2, swap
Опкоды

Арифметические операции
– dadd, ddiv, dmul, dneg, drem, dsub, fadd, fdiv, fmul, fneg, frem, fs
  ub, iadd, idiv, iinc, imul, ineg, irem, isub, ladd, ldiv, lmul, lneg, lre
  m, lsub
Логические операции и операции сдвига
– iand, ior, ishl, ishr, iushr, ixor, land, lor, lshl, lshr, lushr, lxor
Приведение типа
– d2f, d2i, d2l, f2d, f2i, f2l, i2b, i2c, i2d, i2f, i2l, i2s, l2d, l2f, l2i
Безусловный переход
– goto, jsr, ret
Условный переход
– if_acmpeq, if_acmpne, if_icmpeq, if_icmpge, if_icmpgt, if_icmple,
  if_icmplt, if_icmpne, ifeq, ifge, ifgt, ifle, iflt, ifne, ifnonnull, ifnull
Опкоды

Проверка условий
– dcmpg, dcmpl, fcmpg, fcmpl, lcmp, instanceof
Работа с массивами
– Создание и получение размера
    • anewarray, arraylength, multianewarray, newarray
– Установка значения элемента
    • aastore, bastore, castore, dastore, fastore, iastore, lastore, sastore
– Получение значения элемента
    • aaload, baload, caload, daload, faload, iaload, laload, saload
Возврат значения и выбрасывание исключений
– areturn, dreturn, freturn, ireturn, lreturn, return, athrow
Опкоды

Синхронизация
– monitorenter, monitorexit
Создание объекта
– new
Многовариантный выбор
– lookupswitch, tableswitch
Проверка типа
– checkcast
Пустой оператор
– nop
Префикс 16-битных аргументов
– wide
Методы и поля

Опкоды для вызова методов:
–   invokedynamic
–   invokeinterface
–   invokespecial
–   invokestatic
–   Invokevirtual
Чтение и запись значений полей
– getfield, getstatic, putfield, putstatic
Сигнатуры

Всякое обращение к методу или полю содержит сигнатуру
Никакого встраивания
– Кроме static final полей с инициализатором
    •   public static int SIZE = 5;
    •   public static Object x = new Object();
    •   public static String NAME = “name”;
    •   public static String NAME; static {NAME = “name”;}
    •   interface IA { public String x = new Object().toString(); }
Метод или поле выбирается по имени и сигнатуре
Специальные методы <init> и <clinit>
Отладочная информация и исключения

 Code:                                                 public void myMethod() {
  0: iconst_0
  1: istore_1
                                                         try {
  2: goto 10                                                int x = 0;
  5: astore_1                                            } catch (ArithmeticException e) {
  6: aload_1                                                e.printStackTrace();
  7: invokevirtual #23; //Method
java/lang/ArithmeticException.printStackTrace:()V        }
  10: return                                           }
  Exception table:
  from to target type
    0 2 5 Class java/lang/ArithmeticException

LineNumberTable:
 line 32: 0
 line 33: 5
 line 34: 6
 line 36: 10

 LocalVariableTable:
 Start Length Slot Name Signature
 0    11    0 this      LMySample;
 2    3    1 x       I
 6    4    1 e       Ljava/lang/ArithmeticException;
Верификация

Проверка типов
Нет переполнения или опустошения стека
Нельзя перейти по неправильному адресу
Значение записывается в регистр перед чтением из него
Объект инициализируется перед его использованием
Вызовы методов и доступ к полям допустимы
План

Что такое байт-код?
Основные понятия
Соответствие между Java и байт-кодом
Библиотека ASM
JDK 5-7
Классы

     Все становится классом
     Внутренние классы, анонимные классы:
class MyOuterClass$MyInnerClass {                    private class MyInnerClass {
  private int y;                                       private int y;
  private MyOuterClass this$0;                         public MyInnerClass(int y) {
  public MyInnerClass(int y, MyOuterClass $parent)       this.y = y;
{                                                      }
    this.y = y;                                      }
    this.this$0 = $parent;
  }                                                  return new
  static /*synthetic*/ int                           MyInnerClass(5).y;
access$0(MyOuterClass$MyInnerClass c) }
    return c.y;
  }
}

return MyOuterClass$MyInnerClass.access$0(new
MyOuterClass$MyInnerClass(5, this));
Инициализация

Инициализация полей переносится в конструктор /
статические конструктор, кроме примитивных и строковых
констант
private byte[] myArray = {1,2,3,4,5}
–   byte[] x = new byte[5];
–   x[0] = 1
–   … x[4] = 5
–   this.myArray = x;
У интерфейса может быть метод <clinit>, содержащий код
Средства Java в байт-коде

String s = x + “ “ + y;
 – String s = new StringBuilder().append(x).append(“
   “).append(y).toString();
Циклы можно записать при помощи условного перехода
Тернарый оператор записывается через if-else
synchronized(x) {…}
 –   Object $lock = x;
 –   monitorenter($lock);
 –   try {
 –     …; monitorexit($lock);
 –   } catch (Throwable t) {
 –     monitorexit($lock);
 –     throw t;
 –   }
План

Что такое байт-код?
Основные понятия
Соответствие между Java и байт-кодом
Библиотека ASM
JDK 5-7
ASM

Чтение и создание классов
Visitors
Tree
Analysis
XML
ASM visitors

ClassWriter cw = new ClassWriter(false);
cw.visit( ACC_PUBLIC+ACC_ABSTRACT+ACC_INTERFACE,
  "asm1/Notifier", // class name
  "java/lang/Object", // super class
  null,          // interfaces
  "Notifier.java"); // source file

cv = cw.visitMethod( ACC_PUBLIC+ACC_ABSTRACT,
  "addListener",        // method name
  "(Lasm1/Listener;)V", // method descriptor
  null,            // exceptions
  null);           // method attributes

cw.visitEnd();

byte[] bytecode = cw.toByteArray();




                                      Source: http://onjava.com/pub/a/onjava/2004/10/06/asm1.html
ASM visitors

mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();




                          Source: http://www.ibm.com/developerworks/java/library/j-cwt05125/index.html
ASM tree

ClassNode classNode=new ClassNode(4);//4 is just the API version number
classNode.version=Opcodes.V1_6;
classNode.access=Opcodes.ACC_PUBLIC;
classNode.signature="Lcom/geekyarticles/asm/Generated;";
classNode.name="com/geekyarticles/asm/Generated";
classNode.superName="java/lang/Object";
MethodNode mainMethod=new
MethodNode(4,Opcodes.ACC_PUBLIC|Opcodes.ACC_STATIC,"main",
          "([Ljava/lang/String;)V",null, null);
mainMethod.instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System",
          "out", "Ljava/io/PrintStream;"));
mainMethod.instructions.add(new LdcInsnNode("Hello World!"));
mainMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
          "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
mainMethod.instructions.add(new InsnNode(Opcodes.RETURN));
classNode.methods.add(mainMethod);                                     public class com.geekyarticles.asm.Generated {
                                                                         public static void main(String args[]) {
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_MAXS|                   System.out.println(“Hello World!”);
          ClassWriter.COMPUTE_FRAMES);                                   }
                                                                       }
classNode.accept(cw);


                   Source: http://www.javacodegeeks.com/2012/02/manipulating-java-class-files-with-asm_22.html
План

Что такое байт-код?
Основные понятия
Соответствие между Java и байт-кодом
Библиотека ASM
JDK 5-7
foreach loop

for (Type t : i)

aload_1                                                aload_1
dup                                                    invokeinterface java/util/Collection.iterator:()Ljava/util/Iterator;
astore 5                                               astore_3
arraylength                                            goto 27
istore 4                                               aload_3
iconst_0                                               invokeinterface java/util/Iterator.next:()Ljava/lang/Object;
istore_3                                               checkcast class java/lang/String
goto 27                                                astore_2
aload5                                                 getstatic java/lang/System.out:Ljava/io/PrintStream;
iload_3                                                aload_2
iaload                                                 invokevirtual java/io/PrintStream.println:(Ljava/lang/String;)V
istore_2                                               aload_3
getstatic java/lang/System.out:Ljava/io/PrintStream;   invokeinterface java/util/Iterator.hasNext:()Z
iload_2                                                ifne 10
invokevirtual java/io/PrintStream.println:(I)V         return
iinc 3, 1
iload_3
iload4
if_icmplt 12
return
Enum

  Enums
   – создается потомок java.lang.Enum

Compiled from "MyEnum.java"
public final class MyEnum extends java.lang.Enum{
  public static final MyEnum A;
  public static final MyEnum B;
  public static final MyEnum C;
  public static final MyEnum D;
  private static final MyEnum[] ENUM$VALUES;
  static {};
  private MyEnum(java.lang.String, int);
  public static MyEnum[] values();
  public static MyEnum valueOf(java.lang.String);
}
Изменения в JDK 5

    Varargs
    – void myMethod(long a, int… b) -> void myMethod(long a, int[] b)
    Autoboxing
    – Добавляются вызовы методов
    Annotations
    – создается потомок java.lang.annotation.Annotation
    – Аннотации добавлены в формат .class
    – LOCAL_VARIABLE target

Compiled from "MyAnnotation.java"
public interface MyAnnotation extends java.lang.annotation.Annotation{
public abstract java.lang.String name();

public abstract int count();

}
Generics

public class GenericsTest<T, Z extends List<T>> {
  public int myTest(Z z) {
     return z.size();
  }
}

public int myTest(java.util.List);
  Code:
  0: aload_1
  1: invokeinterface #20, 1; //InterfaceMethod java/util/List.size:()I
  6: ireturn
}
Generics

public final class GenericsTest2<T, Z extends ArrayList<T>> extends
GenericsTest<T, Z> {
  public int myTest(Z z) {
     return z.size() + 1;
  }
}

public int myTest(java.util.ArrayList);
 Code:
  0: aload_1
  1: invokevirtual #20; //Method java/util/ArrayList.size:()I
  4: iconst_1
  5: iadd
  6: ireturn

public int myTest(java.util.List);
  Code:
  0: aload_0
  1: aload_1
  2: checkcast       #21; //class java/util/ArrayList
  5: invokevirtual #30; //Method myTest:(Ljava/util/ArrayList;)I
  8: ireturn
}
JDK 7

invokedynamic
– Аналог invokestatic, но сигнатура не содежит имени класса /
  интерфейса
Thank you for your attention!

More Related Content

PPTX
PPTX
Windows Azure and node js
PDF
Объектно-ориентированное программирование. Лекция 5 и 6
PDF
Parallel STL
PDF
C++ refelection and cats
PDF
Очередной скучный доклад про логгирование
PDF
Объектно-ориентированное программирование. Лекции 9 и 10
PPTX
Поговорим о JavaScript, основы и современные тенденции развития языка
Windows Azure and node js
Объектно-ориентированное программирование. Лекция 5 и 6
Parallel STL
C++ refelection and cats
Очередной скучный доклад про логгирование
Объектно-ориентированное программирование. Лекции 9 и 10
Поговорим о JavaScript, основы и современные тенденции развития языка

What's hot (20)

PDF
Использование юнит-тестов для повышения качества разработки
PDF
Java осень 2014 занятие 3
PPTX
Современный статический анализ кода: что умеет он, чего не умели линтеры
PDF
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
PDF
PVS-Studio в 2021 - Примеры ошибок
PDF
Java осень 2014 занятие 5
PDF
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
PDF
Шишки, набитые за 15 лет использования акторов в C++
PDF
Антон Полухин, Немного о Boost
PDF
Архитектура. Доступноять программных систем.
PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
PDF
Объектно-ориентированное программирование. Лекция 7 и 8.
PPTX
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
PDF
Java осень 2014 занятие 6
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
PPTX
Legacy: как победить в гонке (Joker)
PDF
Борис Сазонов, RAII потоки и CancellationToken в C++
PPTX
Александр Фокин, Рефлексия в C++
PDF
C++ STL & Qt. Занятие 01.
PPTX
Статический анализ кода
Использование юнит-тестов для повышения качества разработки
Java осень 2014 занятие 3
Современный статический анализ кода: что умеет он, чего не умели линтеры
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
PVS-Studio в 2021 - Примеры ошибок
Java осень 2014 занятие 5
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Шишки, набитые за 15 лет использования акторов в C++
Антон Полухин, Немного о Boost
Архитектура. Доступноять программных систем.
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Объектно-ориентированное программирование. Лекция 7 и 8.
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Java осень 2014 занятие 6
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Legacy: как победить в гонке (Joker)
Борис Сазонов, RAII потоки и CancellationToken в C++
Александр Фокин, Рефлексия в C++
C++ STL & Qt. Занятие 01.
Статический анализ кода
Ad

Viewers also liked (15)

PPTX
ODP
Использование Qualcomm Augmented Reality в приложениях для Android
PPTX
Object-2-Object mapping, как приправа к вашему проекту
PPTX
Async clinic by by Sergey Teplyakov
PPTX
Spring.new hope.1.3
PPTX
Java 8 in action.jinq.v.1.3
PPTX
Sergey Gavruk - WebMatrix
PPT
Enterprise or not to enterprise
PPTX
ASP.NET MVC 3 Anton Vidishchev
PPTX
Java Performance
PDF
презентация. академическая инициатива Ibm. rus (1)
PPTX
Beginning mef by Владимир Лисник
PPTX
LightSwitch - different way to create business applications
PPTX
Microsoft Test Manager 2010 by Anton Vidishchev
PPTX
Использование Qualcomm Augmented Reality в приложениях для Android
Object-2-Object mapping, как приправа к вашему проекту
Async clinic by by Sergey Teplyakov
Spring.new hope.1.3
Java 8 in action.jinq.v.1.3
Sergey Gavruk - WebMatrix
Enterprise or not to enterprise
ASP.NET MVC 3 Anton Vidishchev
Java Performance
презентация. академическая инициатива Ibm. rus (1)
Beginning mef by Владимир Лисник
LightSwitch - different way to create business applications
Microsoft Test Manager 2010 by Anton Vidishchev
Ad

Similar to Bytecode (20)

PDF
Память в Java. Garbage Collector
PPTX
Android - 02 - annotations, exceptions, io, generics
PDF
UWDC 2013, Yii2
PPTX
Статический анализ кода: Что? Как? Зачем?
PPTX
Поддержка Java 8 в Excelsior JET
PDF
Дмитрий Юницкий. «Android NDK или как я перестал бояться и полюбил нативную р...
PPTX
course js day 2
PDF
C++ осень 2012 лекция 9
PDF
Web осень 2013 лекция 6
PPTX
Зачем нужна Scala?
PDF
[JAM 1.1] Clean Code (Paul Malikov)
PPT
PHP Tricks
PPTX
Принципы работы статического анализатора кода PVS-Studio
PPTX
Вещи в Java, о которых вы (возможно) не знали
PPTX
Convert this: peculiarities of cross-platform mobile game development at Vizor
PDF
Павел Павлов - Scala для профессионалов - Joker 2013
PPTX
Тестирование программных фильтров безопасности
PPTX
C#. От основ к эффективному коду
PPTX
Java весна 2013 лекция 9
PPTX
статический анализ кода
Память в Java. Garbage Collector
Android - 02 - annotations, exceptions, io, generics
UWDC 2013, Yii2
Статический анализ кода: Что? Как? Зачем?
Поддержка Java 8 в Excelsior JET
Дмитрий Юницкий. «Android NDK или как я перестал бояться и полюбил нативную р...
course js day 2
C++ осень 2012 лекция 9
Web осень 2013 лекция 6
Зачем нужна Scala?
[JAM 1.1] Clean Code (Paul Malikov)
PHP Tricks
Принципы работы статического анализатора кода PVS-Studio
Вещи в Java, о которых вы (возможно) не знали
Convert this: peculiarities of cross-platform mobile game development at Vizor
Павел Павлов - Scala для профессионалов - Joker 2013
Тестирование программных фильтров безопасности
C#. От основ к эффективному коду
Java весна 2013 лекция 9
статический анализ кода

More from Alex Tumanoff (20)

PPTX
Sql server 2019 New Features by Yevhen Nedaskivskyi
PPTX
Odessa .net-user-group-sql-server-2019-hidden-gems by Denis Reznik
PPTX
Azure data bricks by Eugene Polonichko
PPTX
Sdlc by Anatoliy Anthony Cox
PPTX
Kostenko ux november-2014_1
PPT
"Drools: декларативная бизнес-логика в Java-приложениях" by Дмитрий Контрерас...
PPTX
Sql saturday azure storage by Anton Vidishchev
PPTX
Navigation map factory by Alexey Klimenko
PPTX
Serialization and performance by Sergey Morenets
PPTX
Игры для мобильных платформ by Алексей Рыбаков
PDF
Android sync adapter
PPTX
Deep Dive C# by Sergey Teplyakov
PPTX
Bdd by Dmitri Aizenberg
PPTX
Неформальные размышления о сертификации в IT
PPTX
Разработка расширений Firefox
PPTX
"AnnotatedSQL - провайдер с плюшками за 5 минут" - Геннадий Дубина, Senior So...
PPTX
Patterns of parallel programming
PPTX
Lambda выражения и Java 8
PPTX
XP практики в проектах с тяжелой наследственностью
PPTX
Anti patterns
Sql server 2019 New Features by Yevhen Nedaskivskyi
Odessa .net-user-group-sql-server-2019-hidden-gems by Denis Reznik
Azure data bricks by Eugene Polonichko
Sdlc by Anatoliy Anthony Cox
Kostenko ux november-2014_1
"Drools: декларативная бизнес-логика в Java-приложениях" by Дмитрий Контрерас...
Sql saturday azure storage by Anton Vidishchev
Navigation map factory by Alexey Klimenko
Serialization and performance by Sergey Morenets
Игры для мобильных платформ by Алексей Рыбаков
Android sync adapter
Deep Dive C# by Sergey Teplyakov
Bdd by Dmitri Aizenberg
Неформальные размышления о сертификации в IT
Разработка расширений Firefox
"AnnotatedSQL - провайдер с плюшками за 5 минут" - Геннадий Дубина, Senior So...
Patterns of parallel programming
Lambda выражения и Java 8
XP практики в проектах с тяжелой наследственностью
Anti patterns

Bytecode

  • 2. План Что такое байт-код? Основные понятия Соответствие между Java и байт-кодом Библиотека ASM JDK 5-7
  • 3. Байт-код Промежуточное представление между Java и машинным кодом Исходный код переводится в байт-код максимально близко либо выражается его средствами Большинство ограничений Java распространяются на байт-код. Source: http://viralpatel.net/blogs/java-virtual-machine-an-inside-story/
  • 4. Что можно делать с байт-кодом? Читать – javap – Анализ классов – Анализ и модификация стороннего кода Создавать – Генерация классов на лету – Компиляция Изменять – AOP – Инструментация – Профилирование Понимать – Франкенбилды
  • 5. Почему он нужен редко? Декомпиляторы – Jad Существующие средства AOP – AspectJ java.lang.reflect.Proxy
  • 6. Средства для работы с байт-кодом ASM CGLIB BCEL SERP Javassist Jasmin Jamaica
  • 7. План Что такое байт-код? Основные понятия Соответствие между Java и байт-кодом Библиотека ASM JDK 5-7
  • 8. Структура класса Все компилируется в .class – Классы – Интерфейсы • <clinit> – Аннотации • java.lang.annotation.Annotation – Перечисления • java.lang.Enum Source: http://viralpatel.net/blogs/tutorial-java-class-file-format-revealed/
  • 9. Стек и регистры Регистры используются для локальных переменных Операции производятся со стеком, например: – public float sum(int a, int b) { return a + b; } становится • iload_1 // положить в стек значение параметра a • iload_2 // положить в стек значение параметра b • Iadd // сложить два верхних элемента стека, результат в стек • I2f // сконвертировать верхний элемент стека из int в float • freturn // вернуть верхний элемент стека В стеке и регистрах хранятся 32-битные значения long и double занимают две ячейки
  • 10. Сигнатуры Z = boolean, C, B, S, I, J = long, F, D Массив: [[Z = boolean[][] Объект: Ljava/lang/Integer; = java.lang.Integer Метод: (II)V = void(int, int) Пример использования: – private Object x = new StringBuffer(); становится • aload_0 • invokespecial java/lang/Object."<init>":()V • aload_0 • new java/lang/StringBuffer • dup • invokespecial java/lang/StringBuffer."<init>":()V • putfield x:Ljava/lang/Object; • return
  • 11. Опкоды Соглашения – Приставки • b, c, s, i, l, f, d • a = reference – iload_0 = iload 0 Работа со стеком – Занесение значения регистра в стек • aload, dload, fload, iload, lload – Перенос верхнего значения из стека в регистр • astore, dstore, fstore, istore, lstore – Запись константы в стек • aconst_null, dconst_{0,1}, fconst_{0,1,2}, iconst_{m1,0,1,2,3,4,5}, lco nst_{0,1}, ldc, ldc2, bipush, sipush – Изменение вершины стека • pop, pop2, dup, dup2, dup2_x1, dup2_x2, dup_x1, dup_x2, swap
  • 12. Опкоды Арифметические операции – dadd, ddiv, dmul, dneg, drem, dsub, fadd, fdiv, fmul, fneg, frem, fs ub, iadd, idiv, iinc, imul, ineg, irem, isub, ladd, ldiv, lmul, lneg, lre m, lsub Логические операции и операции сдвига – iand, ior, ishl, ishr, iushr, ixor, land, lor, lshl, lshr, lushr, lxor Приведение типа – d2f, d2i, d2l, f2d, f2i, f2l, i2b, i2c, i2d, i2f, i2l, i2s, l2d, l2f, l2i Безусловный переход – goto, jsr, ret Условный переход – if_acmpeq, if_acmpne, if_icmpeq, if_icmpge, if_icmpgt, if_icmple, if_icmplt, if_icmpne, ifeq, ifge, ifgt, ifle, iflt, ifne, ifnonnull, ifnull
  • 13. Опкоды Проверка условий – dcmpg, dcmpl, fcmpg, fcmpl, lcmp, instanceof Работа с массивами – Создание и получение размера • anewarray, arraylength, multianewarray, newarray – Установка значения элемента • aastore, bastore, castore, dastore, fastore, iastore, lastore, sastore – Получение значения элемента • aaload, baload, caload, daload, faload, iaload, laload, saload Возврат значения и выбрасывание исключений – areturn, dreturn, freturn, ireturn, lreturn, return, athrow
  • 14. Опкоды Синхронизация – monitorenter, monitorexit Создание объекта – new Многовариантный выбор – lookupswitch, tableswitch Проверка типа – checkcast Пустой оператор – nop Префикс 16-битных аргументов – wide
  • 15. Методы и поля Опкоды для вызова методов: – invokedynamic – invokeinterface – invokespecial – invokestatic – Invokevirtual Чтение и запись значений полей – getfield, getstatic, putfield, putstatic
  • 16. Сигнатуры Всякое обращение к методу или полю содержит сигнатуру Никакого встраивания – Кроме static final полей с инициализатором • public static int SIZE = 5; • public static Object x = new Object(); • public static String NAME = “name”; • public static String NAME; static {NAME = “name”;} • interface IA { public String x = new Object().toString(); } Метод или поле выбирается по имени и сигнатуре Специальные методы <init> и <clinit>
  • 17. Отладочная информация и исключения Code: public void myMethod() { 0: iconst_0 1: istore_1 try { 2: goto 10 int x = 0; 5: astore_1 } catch (ArithmeticException e) { 6: aload_1 e.printStackTrace(); 7: invokevirtual #23; //Method java/lang/ArithmeticException.printStackTrace:()V } 10: return } Exception table: from to target type 0 2 5 Class java/lang/ArithmeticException LineNumberTable: line 32: 0 line 33: 5 line 34: 6 line 36: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this LMySample; 2 3 1 x I 6 4 1 e Ljava/lang/ArithmeticException;
  • 18. Верификация Проверка типов Нет переполнения или опустошения стека Нельзя перейти по неправильному адресу Значение записывается в регистр перед чтением из него Объект инициализируется перед его использованием Вызовы методов и доступ к полям допустимы
  • 19. План Что такое байт-код? Основные понятия Соответствие между Java и байт-кодом Библиотека ASM JDK 5-7
  • 20. Классы Все становится классом Внутренние классы, анонимные классы: class MyOuterClass$MyInnerClass { private class MyInnerClass { private int y; private int y; private MyOuterClass this$0; public MyInnerClass(int y) { public MyInnerClass(int y, MyOuterClass $parent) this.y = y; { } this.y = y; } this.this$0 = $parent; } return new static /*synthetic*/ int MyInnerClass(5).y; access$0(MyOuterClass$MyInnerClass c) } return c.y; } } return MyOuterClass$MyInnerClass.access$0(new MyOuterClass$MyInnerClass(5, this));
  • 21. Инициализация Инициализация полей переносится в конструктор / статические конструктор, кроме примитивных и строковых констант private byte[] myArray = {1,2,3,4,5} – byte[] x = new byte[5]; – x[0] = 1 – … x[4] = 5 – this.myArray = x; У интерфейса может быть метод <clinit>, содержащий код
  • 22. Средства Java в байт-коде String s = x + “ “ + y; – String s = new StringBuilder().append(x).append(“ “).append(y).toString(); Циклы можно записать при помощи условного перехода Тернарый оператор записывается через if-else synchronized(x) {…} – Object $lock = x; – monitorenter($lock); – try { – …; monitorexit($lock); – } catch (Throwable t) { – monitorexit($lock); – throw t; – }
  • 23. План Что такое байт-код? Основные понятия Соответствие между Java и байт-кодом Библиотека ASM JDK 5-7
  • 24. ASM Чтение и создание классов Visitors Tree Analysis XML
  • 25. ASM visitors ClassWriter cw = new ClassWriter(false); cw.visit( ACC_PUBLIC+ACC_ABSTRACT+ACC_INTERFACE, "asm1/Notifier", // class name "java/lang/Object", // super class null, // interfaces "Notifier.java"); // source file cv = cw.visitMethod( ACC_PUBLIC+ACC_ABSTRACT, "addListener", // method name "(Lasm1/Listener;)V", // method descriptor null, // exceptions null); // method attributes cw.visitEnd(); byte[] bytecode = cw.toByteArray(); Source: http://onjava.com/pub/a/onjava/2004/10/06/asm1.html
  • 26. ASM visitors mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); Source: http://www.ibm.com/developerworks/java/library/j-cwt05125/index.html
  • 27. ASM tree ClassNode classNode=new ClassNode(4);//4 is just the API version number classNode.version=Opcodes.V1_6; classNode.access=Opcodes.ACC_PUBLIC; classNode.signature="Lcom/geekyarticles/asm/Generated;"; classNode.name="com/geekyarticles/asm/Generated"; classNode.superName="java/lang/Object"; MethodNode mainMethod=new MethodNode(4,Opcodes.ACC_PUBLIC|Opcodes.ACC_STATIC,"main", "([Ljava/lang/String;)V",null, null); mainMethod.instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")); mainMethod.instructions.add(new LdcInsnNode("Hello World!")); mainMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V")); mainMethod.instructions.add(new InsnNode(Opcodes.RETURN)); classNode.methods.add(mainMethod); public class com.geekyarticles.asm.Generated { public static void main(String args[]) { ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_MAXS| System.out.println(“Hello World!”); ClassWriter.COMPUTE_FRAMES); } } classNode.accept(cw); Source: http://www.javacodegeeks.com/2012/02/manipulating-java-class-files-with-asm_22.html
  • 28. План Что такое байт-код? Основные понятия Соответствие между Java и байт-кодом Библиотека ASM JDK 5-7
  • 29. foreach loop for (Type t : i) aload_1 aload_1 dup invokeinterface java/util/Collection.iterator:()Ljava/util/Iterator; astore 5 astore_3 arraylength goto 27 istore 4 aload_3 iconst_0 invokeinterface java/util/Iterator.next:()Ljava/lang/Object; istore_3 checkcast class java/lang/String goto 27 astore_2 aload5 getstatic java/lang/System.out:Ljava/io/PrintStream; iload_3 aload_2 iaload invokevirtual java/io/PrintStream.println:(Ljava/lang/String;)V istore_2 aload_3 getstatic java/lang/System.out:Ljava/io/PrintStream; invokeinterface java/util/Iterator.hasNext:()Z iload_2 ifne 10 invokevirtual java/io/PrintStream.println:(I)V return iinc 3, 1 iload_3 iload4 if_icmplt 12 return
  • 30. Enum Enums – создается потомок java.lang.Enum Compiled from "MyEnum.java" public final class MyEnum extends java.lang.Enum{ public static final MyEnum A; public static final MyEnum B; public static final MyEnum C; public static final MyEnum D; private static final MyEnum[] ENUM$VALUES; static {}; private MyEnum(java.lang.String, int); public static MyEnum[] values(); public static MyEnum valueOf(java.lang.String); }
  • 31. Изменения в JDK 5 Varargs – void myMethod(long a, int… b) -> void myMethod(long a, int[] b) Autoboxing – Добавляются вызовы методов Annotations – создается потомок java.lang.annotation.Annotation – Аннотации добавлены в формат .class – LOCAL_VARIABLE target Compiled from "MyAnnotation.java" public interface MyAnnotation extends java.lang.annotation.Annotation{ public abstract java.lang.String name(); public abstract int count(); }
  • 32. Generics public class GenericsTest<T, Z extends List<T>> { public int myTest(Z z) { return z.size(); } } public int myTest(java.util.List); Code: 0: aload_1 1: invokeinterface #20, 1; //InterfaceMethod java/util/List.size:()I 6: ireturn }
  • 33. Generics public final class GenericsTest2<T, Z extends ArrayList<T>> extends GenericsTest<T, Z> { public int myTest(Z z) { return z.size() + 1; } } public int myTest(java.util.ArrayList); Code: 0: aload_1 1: invokevirtual #20; //Method java/util/ArrayList.size:()I 4: iconst_1 5: iadd 6: ireturn public int myTest(java.util.List); Code: 0: aload_0 1: aload_1 2: checkcast #21; //class java/util/ArrayList 5: invokevirtual #30; //Method myTest:(Ljava/util/ArrayList;)I 8: ireturn }
  • 34. JDK 7 invokedynamic – Аналог invokestatic, но сигнатура не содежит имени класса / интерфейса
  • 35. Thank you for your attention!

Editor's Notes

  • #2: Hello and welcome to Sigma Ukraine!