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);
}
}
}Регистровые машины
Стековые машины
Структура .class файла. часть III
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
Минорная и Мажорная версия
Размер пула констант
Все константы начинаются с тега
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
name idx
CONSTANT_Utf8_info
bytes
CONSTANT_Class_info
name idx
CONSTANT_Utf8_info
bytes
This class
Super class
INIT
Верификация
Подготовка
Разрешение
Boot Strap
Extension
Application
CLASSLOADER
Загрузка
Линковка
Используются в 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:
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
Состоит из:
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: ireturnputstatic
| 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: ireturnireturn
| 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);
}
} 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 |
Генератор промежуточного кода
Оптимизатор
Генератор нативного кода
Профайлер
Интерпретатор
JNI
JIT
Флаг -o игнорируется с версии java 1.3