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
JRebel
Alex Tumanoff
 
PPTX
Windows Azure and node js
Alex Tumanoff
 
PDF
Объектно-ориентированное программирование. Лекция 5 и 6
Dima Dzuba
 
PDF
Parallel STL
Evgeny Krutko
 
PDF
C++ refelection and cats
corehard_by
 
PDF
Очередной скучный доклад про логгирование
Python Meetup
 
PDF
Объектно-ориентированное программирование. Лекции 9 и 10
Dima Dzuba
 
PPTX
Поговорим о JavaScript, основы и современные тенденции развития языка
Alexander Kucherenko
 
Windows Azure and node js
Alex Tumanoff
 
Объектно-ориентированное программирование. Лекция 5 и 6
Dima Dzuba
 
Parallel STL
Evgeny Krutko
 
C++ refelection and cats
corehard_by
 
Очередной скучный доклад про логгирование
Python Meetup
 
Объектно-ориентированное программирование. Лекции 9 и 10
Dima Dzuba
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Alexander Kucherenko
 

What's hot (20)

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

Viewers also liked (15)

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

Similar to Bytecode (20)

PDF
Joker 2016 - Bytecode 101
Anton Arhipov
 
PPT
Java. Lecture 01. Introducing Java
colriot
 
PPT
Msu.Center.Lectures.J01 Introducing Java
olegol
 
PPTX
Step 1
DmitryTrushkin
 
PDF
Lec 1
Alexander Rusin
 
PPT
01 - Знакомство с Java
phearnot
 
PPTX
Java Core. Lecture# 1. Intro
Anton Moiseenko
 
PPTX
основы Java переменные, циклы
Sergey Nemchinsky
 
PPT
Lec 2 Java
itc73
 
PDF
JPoint 2016 - Bytecode
Anton Arhipov
 
PPTX
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
Fedor Lavrentyev
 
PDF
Иван Иноземцев — Fantom
Yury Yurevich
 
PPT
9. java lecture library
MERA_school
 
PDF
Lec 2
Alexander Rusin
 
PPTX
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Fedor Lavrentyev
 
PDF
Lec 4
Alexander Rusin
 
PDF
Глава1: Обзор технологии Java
metaform
 
PPT
Лекция 6
itc73
 
PDF
02 - Java. Базовый синтаксис Java
Roman Brovko
 
PDF
API design in java project
chashnikov
 
Joker 2016 - Bytecode 101
Anton Arhipov
 
Java. Lecture 01. Introducing Java
colriot
 
Msu.Center.Lectures.J01 Introducing Java
olegol
 
01 - Знакомство с Java
phearnot
 
Java Core. Lecture# 1. Intro
Anton Moiseenko
 
основы Java переменные, циклы
Sergey Nemchinsky
 
Lec 2 Java
itc73
 
JPoint 2016 - Bytecode
Anton Arhipov
 
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
Fedor Lavrentyev
 
Иван Иноземцев — Fantom
Yury Yurevich
 
9. java lecture library
MERA_school
 
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Fedor Lavrentyev
 
Глава1: Обзор технологии Java
metaform
 
Лекция 6
itc73
 
02 - Java. Базовый синтаксис Java
Roman Brovko
 
API design in java project
chashnikov
 

More from Alex Tumanoff (20)

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

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!