g.setStroke(new BasicStroke(params.legendDepth));
g.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20));
int maxL = -1;
List<String> representations = new ArrayList<String>();
for (int i = 1; i <= functionConfigs.size(); i++) {
String representation = String.format("f%d %-15s scale:[%d:%d]", i, functionConfigs.get(i - 1).getRepresentation(), functionConfigs.get(i - 1).getScaleX(), functionConfigs.get(i - 1).getScaleY());
representations.add(representation);
maxL = maxL < representation.length() ? representation.length() : maxL;
}
g.setColor(params.legendRectColor);
g.drawRect(1, 1, maxL * 15, functionConfigs.size() * 20 + 5);
g.setColor(params.legendBkColor);
g.fillRect(2, 2, maxL * 15 - 1, functionConfigs.size() * 20 + 4);
for (int i = 1; i <= functionConfigs.size(); i++) {
g.setColor(params.legendFontColor);
g.drawString(representations.get(i - 1), 5, i * 20);
g.drawRect(maxL * 13, i * 20 - 11, 10, 10);
FunctionConfig functionConfig = functionConfigs.get(i - 1);
g.setColor(functionConfig.getGraphColor());
g.fillRect(maxL * 13 + 1, i * 20 - 10, 9, 9);
if (functionConfig.highlightHigher()) {
g.setColor(params.legendFontColor);
g.drawString(representations.get(i - 1), 5, i * 20);
g.drawRect(maxL * 13 + 20, i * 20 - 11, 10, 10);
g.setColor(functionConfig.heightLightHigherColor());
g.fillRect(maxL * 13 + 21, i * 20 - 10, 9, 9);
}
if (functionConfig.highlightLower()) {
g.setColor(params.legendFontColor);
g.drawString(representations.get(i - 1), 5, i * 20);
g.drawRect(maxL * 13 + 40, i * 20 - 11, 10, 10);
g.setColor(functionConfig.heightLightLowerColor());
g.fillRect(maxL * 13 + 41, i * 20 - 10, 9, 9);
}
}
}


- Краткая история WORA
- Виртуальные машины
-
Регистровые машины
-
Стековые машины
-
- Структура .class файла. часть I
- JVM часть I
- Структура .class файла. часть II
- JVM часть II
-
Структура .class файла. часть III
- JVM часть III
- Оптимизации производимые javac
- Инструментарий
Agenda
Краткая история WORA
Виртуальные машины
Регистровые машины
R1:
100
R2:
135
R3:
0
R1:
100
R2:
135
R3:
ADD
ADD R1 R2 R3
0
235
Стековые машины
10 |
---|
12 |
74 |
23 |
ADD
22 |
---|
74 |
23 |
MUL
1628 |
---|
23 |
POP
POP
_ADD
PUSH
POP
POP
_MUL
PUSH
Структура .class файла. часть I

Минорная и Мажорная версия
Размер пула констант
Все константы начинаются с тега
Пул констант
- Размер пула всегда на один меньше
- Все константы начинаются с тега
- Очень много символьной информации(строки)
- Большинство констант ссылаются на другие константы, почти все в итоге ссылаются на символьные
CONSTANT_NameAndType_info
name idx
descriptor idx
CONSTANT_Utf8_info
bytes
CONSTANT_Utf8_info
bytes
CONSTANT_Fieldref_info
class idx
name&type idx
CONSTANT_Class_info
name idx
CONSTANT_Utf8_info
bytes
Флаги доступа
Флаги доступа - маска флагов, используемых для обозначения прав доступа и свойств этого класса или интерфейса
Например: 0x4001 говорит, что перед нами public enum
0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
---|
1 | 1 | 0 | 0 | 0 | 1 |
---|
public
final
super
interface
abstract
synthetic
annotation
enum
- Класс - ссылка на структуру CONSTANT_Class_info
- Супер класс - ссылка на структуру CONSTANT_Class_info
CONSTANT_Class_info
name idx
CONSTANT_Utf8_info
bytes
CONSTANT_Class_info
name idx
CONSTANT_Utf8_info
bytes
This class
Super class
This&Super&Interfaces
- Список интерфейсов является набором ссылок на CONSTANT_Class_info в пуле констант
JVM часть I
INIT
Верификация
Подготовка
Разрешение
Boot Strap
Extension
Application
CLASSLOADER
Загрузка
Линковка
Предварительные шаги
Структура .class файла. часть II
Аттрибуты
Используются в ClassFile, field_info, method_info, и Code_attribute
name idx
bytes
Length
bytes
attribute_info
CONSTANT_Utf8_info
Поля
name idx
bytes
field_info
access flag
descriptor idx
bytes
attributes
0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
---|
0 | 1 | 1 | 1 | 1 | 1 |
---|
public
final
volatile
synthetic
enum
private
protected
static
transient
CONSTANT_Utf8_info
CONSTANT_Utf8_info
B | byte |
---|---|
C | char |
D | double |
F | float |
I | int |
J | long |
S | short |
Z | boolean |
L | class |
[ | array |
0x004A 0x0012 0x0018 0x0000
модификатор доступа, в данном случае
private static vilotile
атрибутов нет
0x0012 |
---|
0x0A |
0x0004 |
test |
idx:
0x0018 |
---|
0x0A |
0x0001 |
B |
idx:
Пример
Результат:
private static volatile byte test;
Методы
name idx
bytes
method_info
access flag
descriptor idx
bytes
attributes
CONSTANT_Utf8_info
CONSTANT_Utf8_info
0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
---|
1 | 1 | 1 | 1 | 1 | 1 |
---|
public
final
synchronized
abstract
private
protected
static
native
bridge
vararg
strict
synthetic
0x000A 0x0012 0x0019 0x0001 0x0016 0x00000027 ...
модификатор доступа,
в данном случае
private static
один аттрибут, длинной 39 байт
0x0012 |
---|
0x0A |
0x0004 |
test |
idx:
0x0019 |
---|
0x0A |
0x0028 |
(IDLjava/lang/Thread;)Ljava/lang/Object; |
idx:
Пример
Результат:
private static Object test(int v1, double v2, Thread v3) { ... }
0x0016 |
---|
0x0A |
0x0004 |
Code |
idx:
JVM часть II
Method area
Thread 1
Frame N
LVA
OS
FD
Frame 3
LVA
OS
FD
Frame 2
LVA
OS
FD
Frame 1
LVA
OS
FD
Thread stack
Thread 2
Frame N
LVA
OS
FD
Frame 3
LVA
OS
FD
Frame 2
LVA
OS
FD
Frame 1
LVA
OS
FD
Thread stack
Thread N
Frame N
LVA
OS
FD
Frame 3
LVA
OS
FD
Frame 2
LVA
OS
FD
Frame 1
LVA
OS
FD
Thread stack
pc reg 1
pc reg 2
pc reg N
HEAP
Native Method stack
Runtime
Структура .class файла. часть III
Атрибут "Code"
Состоит из:
- максимальный размер для стека операндов(SO) и массива локальных переменных(LVA)
- Собственно код
- Таблица исключений
- Указатель на начало блока try
- Указатель на конец блока try
- Указатель на начало catch блока
- Указатель на класс ожидаемого эксепшена
- Некий набор аттрибутов
Синтаксис Байт-кода
- Большинство операций не требует аргументов
- существует 5ть типа вызова метода:
- invokedynamic - проверка типов происходит в рантайме
- invokestatic - вызывает статический метод
- invokevirtual - вызывает публичные(public) и защищенные(protected) не статические методы
- invokeinterface - вызывает метод интерфейса
- invokespecial - вызывает конструктор или приватные методы или методы родительского класса
- Хорошо описаны в спецификации
Вызовы
public void test() {
// invokespecial #3
// Method java/util/ArrayList."<init>":()V
List<Integer> invokeinterface = new ArrayList<>();
// invokeinterface #5, 2
// InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
invokeinterface.add(1);
ArrayList<Integer> invokevirtual = new ArrayList<>();
// invokevirtual #6
// Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
invokevirtual.add(1);
// invokedynamic #7, 0
// InvokeDynamic #0:run:(Ljava/util/List;)Ljava/lang/Runnable;
Runnable runnable = () -> invokeinterface.add(2);
// invokestatic #8
// Method java/util/Collections.emptyList:()Ljava/util/List;
List<Integer> invokestatic = Collections.emptyList();
}
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
0: getstatic Zax.done
1: aload_0
2: aload_1
3: iconst_0
4: aload_1
Пример
getstatic
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
Zax.done |
---|
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
0: getstatic Zax.done
1: aload_0
2: aload_1
3: iconst_0
4: aload_1
aload_0
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
Zax.done |
---|
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$0 |
---|
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
0: getstatic Zax.done
1: aload_0
2: aload_1
3: iconst_0
4: aload_1
aload_1
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$0 |
---|
Zax.done |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$1 |
---|
var$0 |
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
0: getstatic Zax.done
1: aload_0
2: aload_1
3: iconst_0
4: aload_1
iconst_0
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
0 |
---|
var$1 |
var$0 |
Zax.done |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$1 |
---|
var$0 |
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
0: getstatic Zax.done
1: aload_0
2: aload_1
3: iconst_0
4: aload_1
aload_1
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$1 |
---|
0 |
var$1 |
var$0 |
Zax.done |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
0 |
---|
var$1 |
var$0 |
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
4: aload_1
5: arraylength
6: invokevirtual FileInputStream.read([BII)I
arraylength
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
length |
---|
0 |
var$1 |
var$0 |
Zax.done |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$1 |
---|
0 |
var$1 |
var$0 |
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
4: aload_1
5: arraylength
6: invokevirtual FileInputStream.read([BII)I
invokevirtual
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
read |
---|
Zax.done |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
var$1 |
---|
0 |
var$1 |
var$0 |
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
6: invokevirtual FileInputStream.read([BII)I
7: iadd
8: dup
iadd
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
res |
---|
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
read |
---|
Zax.done |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
6: invokevirtual FileInputStream.read([BII)I
7: iadd
8: dup
dub
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
res |
---|
res |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
res |
---|
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
8: dup
9: putstatic Zax.done
10: ireturn
putstatic
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
res |
---|
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
res |
---|
res |
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
8: dup
9: putstatic Zax.done
10: ireturn
ireturn
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
LVA | OS |
---|
idx | val |
---|---|
0 | var$0 |
1 | var$1 |
res |
---|
Destroy
Frame
public static int readIn(FileInputStream var$0, byte[] var$1) {
//Max stack: 5, Max locals: 3, Code length: 27b
//Code:
0: getstatic Zax.done
1: aload_0
2: aload_1
3: iconst_0
4: aload_1
5: arraylength
6: invokevirtual FileInputStream.read([BII)I
7: iadd
8: dup
9: putstatic Zax.done
10: ireturn
11: astore_2
12: new
13: dup
14: aload_2
15: invokespecial RuntimeException.<init>(Ljava/lang/Throwable;)V
16: athrow
}
public static int readIn(FileInputStream fis, byte[] arr) {
try {
return done += fis.read(arr, 0, arr.length);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Байт-код
Java-код
public static int readIn(java.io.FileInputStream, byte[]);
Code:
0: getstatic #12 // Field done:I
3: aload_0
4: aload_1
5: iconst_0
6: aload_1
7: arraylength
8: invokevirtual #11 // Method java/io/FileInputStream.read:([BII)I
11: iadd
12: dup
13: putstatic #12 // Field done:I
16: ireturn
17: astore_2
18: new #36 // class java/lang/RuntimeException
21: dup
22: aload_2
23: invokespecial #37 // Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V
26: athrow
Таблица исключений
start pc | end pc | handler pc | catch type |
---|---|---|---|
0 | 16 | 17 | Class java/io/IOException |
JVM часть III
Генератор промежуточного кода
Оптимизатор
Генератор нативного кода
Профайлер
Интерпретатор
JNI
Исполнение
JIT
Оптимизации производимые javac
Почти никаких - все на откуп JIT
Флаг -o игнорируется с версии java 1.3
Инструменты
Генерация кода
Декомпиляция
Q/A
Java Once; Java Anywhere
By Roman Makhlin
Java Once; Java Anywhere
- 514