Folien vom 29.10.2001

Werbung
Projektgruppe “Verteilung von parallelen Java-Anwendungen”
JV
• Struktur von Klassendateien
• Befehlssatz der JVM
• Übersetzung grundlegender
Java-Konstrukte
• Wichtige Java-Konstrukte mit
komplexerer Umsetzung
M
Java-Bytecode:
Der Blick unter die Haube
Michael Thies, 29.10.2001
JV
M
Übersetzen und Ausführen von Java-Programmen
1
Laufzeit
Benutzer-Eingaben
Bildschirm-Ausgaben
Java Laufzeitumgebung
Quelltext
Ausführung
CodeErzeugung
ClassLoader
Linker
Java Compiler
BytecodeErzeugung
0110
11001110
01110001
11001111
01011000
binäre
Klassendatei
0110
11001110
01110001
11001111
01011000
weitere Dateien
jar-Datei
JV
M
Struktur einer Java-Klasse: Quelltext
2
package de.upb.example;
public abstract class NamedDemo
extends AbstractDemo
implements Runable
{
Angaben zur Klasse
protected String name;
private static int count = 0;
public static final int NO_DEMO = -1;
Definition von Klassen-/
Instanzvariablen
public String getName() { return name; }
public void run() { doDemo(); }
static int getCount() { return count; }
public NamedDemo(String n)
{ name = n; }
protected abstract void doDemo();
}
Definition von Methoden,
Konstruktoren
JV
M
Struktur einer Java-Klasse: binäre Klassendatei
3
NamedDemo.class
Kopf
Kennung: 0xCAFEBABE
Version: 45.3
ConstantPool
Tabelle mit Namen, externen Referenzen
Klassen-Definition
Name: de.upb.example.NamedDemo
Oberklasse: de.upb.example.AbstractDemo
Interfaces: java.lang.Runable
Eigenschaften: public, abstract
Feld-Definitionen
Methoden-Definitionen
name
getName
count
getCount
NO_DEMO
run
<init>
doDemo
JV
M
Attribute: Bausteine der Information in Klassendateien
4
Klassendatei
Kopf
ConstantPool
Klassen-Definition
Attribute
Name, Länge der Daten
Name, Länge der Daten
Name, Länge der Daten
zugehörige
?
zugehörige
?
Daten
zugehörige
?
Daten
Daten
Feld-Definition
Feld-Definition
Methoden-Definition
Methoden-Definition
Liste von Attributen
standardisierte Attribute:
• Pflicht-Attribute
– Bytecode für Methoden
'Code'
– Werte für Konstanten
'ConstantValue'
• optionale Attribute
– Informationen für Debugger
'LineNumberTable',
'SourceFile'
JV
M
Definition von Feldern (Klassen-/Instanzvariablen)
5
Feld-Definition
• Name des Feldes
• deklarierter Typ
• Eigenschaften:
– Sichtbarkeit
– Instanz- oder Klassenfeld
– Sonstige: final, transient, volatile
• Wert von Konstanten
Beispiele:
Feld-Definition
Name: name
Typ: String
Eigenschaften: protected, nicht static
Feld-Definition
Name: count
Typ: int
Eigenschaften: private, static
Feld-Definition
Name: NO_DEMO
Typ: int
Eigenschaften: public, static, final
Attribut
Name: 'ConstantValue'
Länge: 2
Inhalt: (int, -1)
JV
M
Typangaben in Klassendateien
6
kompakte Textdarstellung für alle Java-Typdeklarationen:
1. Großbuchstaben für Grundtypen
in Java
int
double
float
long
boolean
in der Klassendatei
I
D
F
J
Z
2. vollständige Klassennamen für Referenztypen
• eingeschlossen in L und ;
• ähnlich wie Pfadangaben unter UNIX mit / als Trennzeichen
in Java
in der Klassendatei
Object
Ljava/lang/Object;
java.lang.String
Ljava/lang/String;
de.upb.example.NamedDemo Lde/upb/example/NamedDemo;
3. Anzahl Dimensionen und Elementtyp für Array-Typen
• jede Dimension durch Präfix [ repräsentiert
in Java
in der Klassendatei
float[][]
[[F
String[]
[Ljava/lang/String;
7
JV
M
Definition von Methoden
Methoden-Definition
• Name der Methode
• Signatur der Methode
• Eigenschaften:
– Sichtbarkeit
– Instanz- oder Klassenmethode
– Sonstige: final, abstract, native,
synchronized
• ausgelöste, geprüfte Ausnahmen
Attribut 'Exceptions'
• Implementierung der Methode
Attribut 'Code'
Beispiele:
Methoden-Definition
Attribut
Name: getName
Name: 'Code'
Signatur: () → void
Länge: n1
Eigenschaften: public, nicht static Inhalt: Bytecode
Methoden-Definition
Methoden-Definition
Name: doDemo
Signatur: () → void
Eigenschaften: protected,
nicht static,
abstract
Attribut
Name: <init>
Name: 'Code'
Signatur: (String) → void
Länge: n2
Eigenschaften: public, nicht static Inhalt: Bytecode
Konstruktor
JV
M
Methoden-Signaturen als Erweiterung der Typangabe
8
kompakte Textdarstellung für Parametertypen und Ergebnistyp:
'(' Parametertyp∗ ')' Ergebnistyp
Parametertyp, Ergebnistyp: wie bei Typangaben für Felder
zusätzlich V für Ergebnistyp void
Beispiele:
Methodenkopf in Java
String getName()
void setName(String n)
boolean find(double[] v, float f)
Signatur in der Klassendatei
()Ljava/lang/String;
(Ljava/lang/String;)V
([DF)Z
Überschreiben von Methoden aus Sicht der JVM:
Methodenname und Textdarstellung der Signaturen
müssen in Ober- und Unterklasse gleich sein
JV
M
Architektur und Befehlssatz der Java Virtual Machine (JVM)
9
JVM
ThreadScheduler
Java-Bytecode
• Befehlssatz eines abstrakten Prozessors
• stark auf Java zugeschnitten
• 0-Adressmaschine (Kellerarchitektur)
mit zusätzlichen Registern
ClassLoader
Abstrakter
Prozessor
Linker
Finalizer
Garbage
Collector
0
1
2
3
• Befehle sind typisiert (die meisten)
• keine Typinformation für
Kellerelemente und Register
• Bytecode-Verifikation leitet
Typinformation her und prüft
Konsistenz
Typ int
float double Objektreferenz
fadd dadd
—
fmul dmul
—
Operation
Addition
iadd
Multiplikation imul
Ergebnisireturn freturn dreturn
rückgabe
Vergleich
if_icmp fcmp
dcmp
areturn
if_acmp
10
JV
M
Java-Bytecode: Struktur des Befehlssatzes
unterstützte Datentypen:
•
•
•
•
int, float, Objektreferenzen
long, double
eingeschränkt: byte, short, char
gar nicht: boolean
Größe: 1 JVM-Wort
Größe: 2 JVM-Worte
↔ int
202 verschiedene Bytecode-Befehle
darunter viele spezielle Kurzformen (CISC-artig)
Befehlsgruppen:
• Arithmetik
• Datentransport
– Konstanten laden
– Werte transportieren
• Sprungbefehle (bedingt/unbedingt)
• Zugriffe auf Felder
• Methodenaufruf und -rücksprung
• spezielle Unterstützung für Java
– Objekterzeugung
– Typtest und Typumwandlung
– Exceptions auslösen
–…
const
0
1
2
3
universeller abstrakter Prozessor
Java-spezifischer abstrakter Prozessor
JV
M
Kellerarchitektur: Arithmetik mit der JVM
11
Bytecode:
iconst 3
iconst 4
iadd
iconst 6
imul
4
3
iadd
6
7
imul
7
Ausdrücke in Postfix-Form:
(3 + 4) ∗ 6 → 3
4
+
iconst 3
iconst 4 iadd
42
6
∗
iconst 6 imul
12
JV
M
Speichermodell der JVM
Methode m
Bytecode hat Zugriff auf:
global
lokal für Methode (mit fester Größe)
dup,
Arithmetik
putstatic
Objekt
Klasse
Tstore
getstatic
Tload
putfield
Objekt
Objekt
getfield
Objektspeicher
(heap)
Operandenkeller
0
1
2
3
4
5
6
7
Register
(lokale Variablen)
JV
M
Übersetzung: Zugriffe auf Klassen-/Instanzvariablen
13
Lesen
Klassenvariable
int i = NamedDemo.count;
getstatic <NamedDemo.count>
istore 3
Reg. 3 ist i
Instanzvariable
Schreiben
NamedDemo.count = 0;
iconst 0
putstatic <NamedDemo.count>
int i = this.age;
this.age = 18;
aload 0
aload 0
iconst 18
putfield <Person.age>
getfield <Person.age>
istore 3
Reg. 3 ist i
JV
M
Kontrollfluß: Sprünge und Distanzen
14
Fallunterscheidung
if (x > y)
this.max = x;
else
this.max = y;
0:
1:
2:
5:
6:
7:
10:
13:
14:
15:
18:
iload 2
Reg. 2 ist x
iload 3
Reg. 3 ist y
if_icmple +11
aload 0
iload 2
putfield <Cond.max>
goto +8
aload 0
iload 3
putfield <Cond.max>
…
Byte-Offsets
im Bytecode
abweisende Schleife
int res = 1;
int
i = 0;
while (i < 7)
{
res = 5 * res;
i = i + 1;
}
0:
1:
2:
3:
4:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
18:
21:
iconst 1
istore 2
Reg. 2 ist res
iconst 0
istore 3
Reg. 3 ist i
goto +11
iconst 5
iload 2
imul
istore 2
iload 3
iconst 1
iadd
istore 3
iload 3
iconst 7
if_icmplt -11
…
JV
M
Übersetzung von Methodenaufrufen
15
Klassenmethode
int v, w = 9;
v = Math.max(-w, 0);
0:
2:
3:
4:
5:
6:
9:
10:
iconst 9
istore 3
Reg. 3 ist w
iload 3
ineg
iconst 0
invokestatic <Math.max>
istore 2
Reg. 2 ist v
…
Instanzmethode
Graphics g;
g.drawString(20, 30, "Hallo");
0:
1:
3:
5:
7:
10:
aload 4
Reg. 4 ist g
iconst 20
iconst 30
ldc "Hallo"
invokevirtual <Graphics.drawString>
…
16
JV
M
Ausführung von Methodenaufrufen
Treturn
invokexxx
2 Parameter
Schachtel aufgerufene Methode
Laufzeitkeller
Schachtel Aufrufer
0
1
2
3
Parameterübergabe
0
1
2
3
4
5
0
1
2
3
4
5
0
1
2
3
0
1
2
3
Ergebnisrückgabe
17
JV
M
Bindung von Methodenaufrufen
Bytecode-Befehl
Bindung
Empfänger Beispiel-Situation
(this)
invokevirtual
dynamisch (Klasse)
ja
Component c;
c.repaint();
invokeinterface
dynamisch (Interface)
ja
Enumeration elems;
elems.nextElement();
invokestatic
statisch
nein
Thread.sleep(1000);
invokespecial
statisch
ja
super.paint(g);
Ausführung dynamischer Methodenbindung:
0: aload 3
1: invokevirtual <Component.repaint>
4: …
JVM wählt Implementierung von repaint()
gemäß Typ der Objektreferenz auf dem Keller aus.
Component
• repaint()
TextArea
Label
• repaint()
• repaint()
JV
M
Java-Bytecode: Befehle kompakt codiert
18
Beispiel: int-Konstanten kellern
Wertebereich
Befehl
Format
Länge
–1, …, 5
iconst_n
0x02, …, 0x08
1
-128, …, 127
bipush n
0x10 n
2
-32768, …, 32767
sipush n
0x11 n1 n2
3
Sonstige
ldc idx, ldc_w idx
0x12 idx, 0x13 idx1 idx2
2 + 4, 3 + 4
Beispiel: Objektreferenz im Register kellern
Register-Nr.
Befehl
Format
Länge
0, …, 3
aload_n
0x2a, …, 0x2d
1
4, …, 255
aload n
0x19 n
2
256, …, 65535
wide aload n
0xc4 0x19 n1 n2
4
Spezialbefehl für häufiges Idiom: lokale Variable inkrementieren/dekr.
iload n
iconst c
iadd
istore n
iinc n, c
im besten Fall: 3 statt 7 Bytes
19
JV
M
Klassendateien: kompakt dank ConstantPool?
ConstantPool
Quelltext
Index Eintragstyp
Daten
1
2
3
4
5
6
7
8
Hello!
Index 1
java/lang/String
Index 3
length
()I
Indizes 5, 6
Indizes 4, 7
UTF8
String
UTF8
Class
UTF8
UTF8
NameAndType
Methodref
"Hello!".length()
Bytecode
ldc #2
invokevirtual #8
String
Methodref
"Hello!"
Einträge im ConstantPool
Class
"java/lang/String"
Typ des Empfängers
NameAndType
"length"
"()I"
Methodenname
Signatur
• ConstantPool speichert identische Einträge nur einmal
• macht im Mittel 60% der Größe einer Klassendatei aus
Herunterladen