Java Virtual Machine (JVM) Alan Dingwall [email protected] Übersicht • • • • • • Was ist die Java Virtual Machine? Das Class File Format Aufbau der JVM Kompilation .java .class Fazit Quellennachweise Was ist die JVM? • Abstrakter Prozessor • Führt Class Files aus • Grund für die Plattformunabhängigkeit von Java • JVM kennt die Sprache Java nicht – Alternative Programierspachen für die JVM Das Class File Format • Kompilierte Java-Klassen und Interfaces werden in Class Files gespeichert (*.class). • Daten sind big-endian Struktur einer Class File Name magic Size Name Size 4 interfacesCount 2 minorVersion majorVersion 2 2 interfaces fieldsCount N/A 2 constantPoolCount constantPool accessFlags thisClass 2 N/A 2 2 fields methodsCount methods attributesCount N/A 2 N/A 2 superClass 2 attributes N/A magic ist immer 0xCAFEBABE Der Constant Pool • Enthält alle Konstanten einer Klasse • Eintragstypen: Tag Name Value Followed by Utf8 Integer ... Class String Fieldref Methodref InterfaceMethodref NameAndType 0x01 0x03 ... 0x07 0x08 0x09 0x0A 0x0B 0x0C u2 length, u1 data[length] integer ... u2 name u2 string u2 class, u2 nameAndType u2 class, u2 nameAndType u2 class, u2 nameAndType u2 name, u2 descriptor Die Attributes Tabelle • Enthält zusätzliche Informationen z.B. Instruktionen ,Source File, Zeilentabellen • Struktur der Einträge: attributeInfo Name Size nameIndex length info 2 4 lenght Die Fields Tabelle • Enthält Deklaration der Felder • Struktur der Einträge: fieldInfo Name Size accessFlags nameIndex descriptorIndex attributesCount attributesInfo 2 2 2 2 N/A Die Methods Tabelle • Enthält Deklarationen der Methoden • Struktur der Einträge: methodInfo Name Size accessFlags nameIndex descriptorIndex attributesCount attributesInfo 2 2 2 2 N/A Beispiel HelloWorld(1) • HelloWorld.java public class HelloWorld { public static void main(String args[]) { System.out.println("Hello World!"); } } Beispiel HelloWorld(2) • Hex Dump BA 00 01 00 62 00 74 65 6C 00 6C 6C BE 11 00 04 65 16 72 46 64 18 64 6C 00 08 06 43 72 28 69 69 2E 00 21 6F 03 00 3C 6F 54 5B 6E 6C 6A 19 07 57 00 12 69 64 61 4C 67 65 61 01 00 6F 2D 0A 6E 65 62 6A 3B 01 76 00 1A 72 00 00 69 01 6C 61 29 00 61 0C 0C 6C 1D 13 74 00 65 76 56 0F 0C 48 00 64 0A 00 3E 0F 01 61 01 48 00 65 1B 01 00 14 01 4C 00 2F 00 65 07 6C 00 00 06 07 00 69 04 6C 0A 6C 00 6C 1C 10 00 00 03 6E 6D 61 53 6C 08 6F 01 6A 0F 15 28 65 61 6E 6F 6F 07 20 00 61 09 07 29 4E 69 67 75 57 00 57 0A 76 .......-........ ................ .....<init>...() V...Code...LineN umberTable...mai n...([Ljava/lang /String;)V...Sou rceFile...HelloW orld.java....... .........Hello W orld!........... HelloWorld...jav Aufbau der JVM Exception Manager ss Cla der a Lo ry mo Me nager Ma Excecution Engine Native Interface T Sc hrea he d du ler FE 10 16 01 6D 01 53 63 72 0C 72 65 Se Ma curity nag er CA 00 00 56 75 6E 2F 72 6F 17 6F 48 Excecution Engine • Virtueller Prozessor • Stack-Orientiert • Instruktionssatz mit 201 versch. Opcodes Datentypen der Execution Engine Prefix Type Interpretation b byte signed byte c char unicode character d double double-precision floating point value f float single-precision floating point value i int integer l long long integer s Short signed short a Reference references an object ReturnAddress Used by jsr,ret,... Datenbereiche Java Stack Frame Frame Frame Frame Register Programmzähler Aktuelles Frame Oberster Operand Lokale Variablen Garbage Collected Heap Object 1 Methodenbereich Aktueller Frame Aktuelle Klasse Aktuelle Methode Constant pool Operanden Stack Lokale Variablen Befehlssatz • • • • 1 Byte langer Opcode Je nach Opcode gefolgt von Operanden Typisiert Nicht orthogonal Instruktionsklassen • • • • • • • • • • Konstanten auf den Stack schieben Lokale Variablen laden und speichern Stackmanipulationen Arithmetische und Logische Operationen Flusskontrolle Arrayoperationen Castingoperationen Manipulieren von Feldern Methodenaufruf und Rücksprung Andere Instruktionen (1) iadd Addiert zwei Integer auf dem Stack int2 int1 int1 + int2 ? ? ? ? Operanden Stack Operanden Stack Andere arithmetische Befehle: ladd, fadd, dadd, isub, lsub, fsub, dsub, imul, lmul, fmul, dmul, idiv, ldiv, fdiv, ddiv, irem, lrem, frem, drem, ineg, lneg, fneg, dneg Instruktionen (2) dup Oberstes Stackelement duplizieren objref objref objref ? ? ? ? Operanden Stack Operanden Stack Andere Stack-Befehle: dup2, pop, pop2, swap... Instruktionen (3) bipush n ldc #n iconst_<n> byte-Konstante als Integer auf den Stack schieben 32bit Constant Pool Konstante auf den Stack schieben Int-Konstante auf den Stack schieben <n>=m1,0,1,2,3,4,5 Andere Stack-Befehle: sipush, ldc_w, ldc2_w, lconst_0, lconst_1, fconst_0, fconst_1, fconst_2, dconst_0, dconst_1 Instruktionen (4) iload n iload_<n> lokale Variable auf den Stack „pushen“ lokale Variable auf den Stack „pushen“ <n>=0..3 istore n lokale Variable vom Stack holen istore_<n> lokale Variable vom Stack holen <n>=0..3 Andere Befehle: lload, lload_<n>, fload, fload_<n>, dload, dload_<n>, aload, aload_<n>, lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>, Instruktionen (5) iinc v n lokale Variable v um n erhöhen iload wide v iload n v high v low n high n low Instruktionen (6) invokevirtual #n return Methode aufrufen Rücksprung aus einer Methode invokestatic, invokespecial, invokeinterface, ireturn, lreturn, freturn, dreturn, areturn old frame new frame arg2 arg1 objref objref arg1 arg2 ? stack local vars stack local vars Wie funktioniert die Execution Engine? ... while(!finished) switch(bytecode[pc]) { ... case IADD: int i=stack.popInt(); int j=stack.popInt(); stack.push(i+j); pc++; break; ... } ... Ablauf beim Start der JVM • • • • java HelloWorld VM versucht HelloWorld.main auszuführen ClassLoader (lädt HelloWorld.class) Linking – Verifikation – Preparation – (Resolution) (Testet die Gültigkeit der Klasse) (Speicher für statische Var. allozieren,...) (Symbolische Referenzen überprüfen) • Initialisation (Statische Init-Funktionen ausführen) • Ausführen von HelloWorld.main • Wenn kein Thead mehr läuft wird die VM beendet Verifikation • Durchgang 1 – File befolgt das Class File Format • Durchgang 2 – Klasse besitzt Superklasse (nicht final) – Indexe im Constant Pool verweisen auf den korrekten Typ – Namen und Typen von Methoden und Feldern sind erlaubt • Durchgang 3 (Bytecode Verifier) – Überprüft Methodencode Bytecode Verifier • • • • Sprungziele innerhalb der Methode Deklarierte Anzahl lokaler Variablen wird eingehalten Constant Pool Indexe verweisen auf korrekten Typ Data-flow Analyser – Stackgrösse wird eingehalten – Lokale Variablen und Stack beinhalten die von der Instruktion benötigten Typen – Für jeden Weg zu einer Instruktion sind die Anzahl und der Typ der Elemente des Stacks identisch Java Bytecode (1) public int addMethod(int a,int b) { return a+b; } Method int addMethod(int,int) 0 iload_1 1 iload_2 2 iadd 3 ireturn Java Bytecode (2) public void objectMethod() { Compiler a=new Compiler(); int i=a.addMethod(10,20); } Constant Pool: #2 <Class Compiler> #3 <Method Compiler()> #4 <Method int addMethod(int, int)> Java public void forMethod() { int s=1; for(int i=0;i<10;i++) s*=i; } Method void objectMethod() 0 new #2 3 dup 4 invokespecial #3 7 astore_1 8 aload_1 9 bipush 10 11 bipush 20 13 invokevirtual #4 16 istore_2 17 return Bytecode (3) Method void forMethod() 0 iconst_1 1 istore_1 2 iconst_0 3 istore_2 4 goto 14 7 iload_1 8 iload_2 9 imul 10 istore_1 11 iinc 2 1 14 iload_2 15 bipush 10 17 if_icmplt 7 20 return Java public void arrayMethod() { int a[]=new int[10]; a[4]=a[3]; } Bytecode (4) Method void arrayMethod() 0 bipush 10 2 newarray int 4 astore_1 5 aload_1 6 iconst_4 7 aload_1 8 iconst_3 9 iaload 10 iastore 11 return Fazit • Grosses Thema • Zeigt mögliche Code-Optimierungen • Information im Internet ist oft fehlerbehaftet Quellenangaben • Java Virtual Machine Specification http://java.sun.com/docs/books/vmspec/index.html • Languages for the Java Virtual Machine http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html • JAVA Virtual Machine (Meyer, Downing) • Developing Professional Java Applets (Hopson, Ingram) http://www.kaposnet.hu/books/profiapplet/appa.htm