6 High-Level Language Virtual Machine Implementation VM Architektur: Klassen und Mehoden Bestandteile einer HLL VM implementation: ‐ Class loader subsystem ‐ The memory system, including a garbage‐collected heap ‐ Emulation engine (sometimes referred to as the execution engine) ‐ native method interface Memory and State Registers Area für 1. Programmencode, 2. global memory area, stacks für 3. Java Kode und 4. native library Programmcode von den Program Counter beigetreten Stack hat ein stackpointer (ein Register) als counter und keine fixe grosse: stackOvrflowError Memory ist ein Heap, grosse wird nicht wordefiniert : OutOfMemoryError Garbage Collector Garbage sind die nicht mehr genutzten (referenzierte) Objekte. Sie werden von Garbage collected. Emulation Engine Von Native Methoden unterstutzt. Interpretation oder volle Translation (Kompilation). Kann auch Profilierung und staged emulation hotspots, translation machen. Pretranslation, wie nutztung von constant var, werden gemacht. Native Method Interface Set von Standard Libraries I/O. Calls zu OS mit native Methoden gemacht Class Loader Subsystem Sucht die Klasse, dynamisch in system oder Netz. Verifizier, dass die Klassen korrekt sind. 6.1 Dyanamic Class Loading Findet, prüft und übersetzt die Klasse. Variable, Method, data müssen zugänglich sein. Package: logische Klassen gruppierung. Fully qualified name: package name, class name, method or var name. In Netz wird die internet Domain gegeben. - in Netzt betrachtet werden die Rechte auf den lokalen system - allen Klassen im gleichen Package - public: von anderen Packages - Felder von gleichen Klasse zugänglich, wenn nicht private auch von anderen Klassen zugänglich. Primordial Class Loader, trusted JVM component. Namespaces: Klassen können nicht interagieren, sind von unterschiedlichen Klassen loader geladen. Übersetzung von binary class consistency check (magic number), kann nummer und typ von argumenten checken. Fully qualified references werden gelöst in direct reference (on demand). Integrität: static type check, reference in bound check, branches instruction in Procedure. Nach der Initalisierung: Kontrolle wird zum Emulation gegeben 6.2 Implementing Securtiy Sandbox ist die default security in Java, isoliert die Ausführung des Programmes. Sandbox‐Vorraussetzungen: 1. Remote‐Dateien müssen geschützt werden. Von OS system, wie jede andere eigene Ressource. 2. Lokale Dateien müssen vor einem laufenden Java‐Programm geschützt werden: mit Security Manager 3. Java Kode und Data müssen vor einem laufenden Java‐Programm geschützt werden. z.B: sollte nicht Site Table schreiben, nicht Jumpen zu beliebige Memory. Dank Kombination von statische und dynamische checking. 6.2.1 Interprocess Protection 1 Oft wird ein fremdes Programm ausgeführt: darf nur eigene Memory Location beitreten und trusted code via calls to library ausführen. P-Code wird kompiliert mit statischen Daten, dann an verschiedene Plattformen gegeben. Sie müssen dem Code vertrauen. Data Strukturen (Metadata) wird übermittelt: Konsistenz Metadata-Code wird geprüft. Type und Kontrol-Flow wird geprüft. Interprozess-Protection: 1. Access zu Daten der eigene memory Bound, 2. Keine Branche ausserhalb der Code, nur Library calls. 1. Loader: Daten von Constant, prüfen nach Referenzen. 2. In Stack werden Typen und Anzahl an operandi getrackt 3. Access zum global memory. Index check dynamisch. Array Size auch dynamisch geprüft. Check nach Null wert. 4. Upcatsing und downcasting ist erlaubt. Keine unerlaubte Memory access: statisch und dynamisch 6.2.2 Security Enforcement Java.lang API reading, writing, opening file Java.io API interact mit Host OS. Recurrent vs deep anfrage sind nicht möglich. (DoS) 6.2.3 Enhaced Security Model Geht weg von alles oder nichts. Signing: sichere Identifizierung von Ressourcen. Hashed und mit Public Key encrypted Das ist eine granulierte Möglichkeit, die Sicherheit des Programm zu prüfen. Problem by nested request, unsichere Methode ruft eine sichere Methode. Stack erweitert mit: Principal information, premissions. Abrufe werden in der umgekehrte Ordnung geprüft: von geschachtelte Funktion abrufe nach oben. Erweitertes Sicherheitsmodell: Unterstützt Access Control 6.3 Garbage Collection OutOfMemory exeption. Beispiel mit objekten im GlobalMemory heap. Man started von Root Pointer, werden reference inkludiert 1. Finde root pointers 2. Starte vom root pointer und durchlaufe Referenzen. Dabei werden alle accessed Obj gefunden. 3. Die nicht erreichten Objekte sind Garbage / Müll. Tradeoff: object-allocation, object-access, efficiency von der Nutzung von Heap Space. Manche GC zählen die Referencen im Heap. Üblich ist der top-down System. Unerreichbare Objecte sind Müll 6.3.1 Mark-and-Sweep Collectors Start von Root, markiert alle Objekte die erreicht werden. Zweimal erreichte Objekte werden nicht tiefer untersuchet. Sweep phase – checking and collecting Garbage. Dynamische Memory hat mehr garbage funktions. Konsolidierung von Garbage Platz: copy oder Kompakt. 6.3.2 Compacting Collector Slide Live Objekte zum Schluss der Heap. Ist langsam und mehr Stufig: marking, moving, updating references. Handle pool: indirekte Referenz zum Object (+ schnelle update, - mehr indirekten) 6.3.3 Copying Collectors Heap in 2 geteilt. Objekte werden im leeren Heap ordentlich verschoben. Ist schneller aber braucht mehr Ressourcen. 6.3.4 Generational Collectors Viele Objecte leben kurz, andere sehr lang. 2 Subheaps 2 Tenuerd: langdauernde Objecte, GC nicht so oft. Mit mark-and-sweep. Nursery : normale Object, von hier werden die nach ein paar Ziklen in Tenuerd verschoben. Diese kleinere portion wird GC. Mit copy-collector. 6.3.5 Incremental and Concurrent Collectors Stopt nicht die Programmausführung. Incremental: mit Teile des Programmes Concurrent: mit threads Beide brauchen Synchronisierung mit Program-GB. Zwischen Pointers und tracing reference path Stop-and-collect Method: write barrier. 6.3.6 Discovering the Root Set Side Table, so compiler (optimizer findet den root set). Das ist type accurate oder exact approach. Andere möglichkeit: alle pointer die möglicherweise den root pointer enthalten als root pointer betrachten root superset. Moving ist nicht möglich, weil falsche Objecte dem echten schaden können. 6.3.7 Garbage-Collection Summary Die method hängt von Working size, Object size, Heap size ab. Tabelle 6.1 Seite 303. Generationelle Collect ist ein sehr gutes Vorgehen, Reduziert die Zeit für Collection. 6.4 Java Native Interface Native Methode haben ihren eigenen Plattform abhängige Stack. Array von Native Methoden müssen vor Garbage Collector geschützt werden. Pin: reference will nicht bewegt oder collected sein. 6.5 Basic Emulation Verwendet: ‐ Straight‐foreward compiler (Konventionelle ISA). Interpretation, Just-in-Time compilation. Method at a time. ‐ Just‐in‐time compiler (Moderne ISA) , gleich als tanslator. Kein frontend, syntax check vor Übersetzung in Intermediate code. Just‐in‐time compiler sind standardmäßig in Java aktiviert, um Methoden beim ersten Aufruf bereits zur Verfügung zu haben. Dynamic, run time compiler macht mehr optimization als der statische. JIT Optimierungen werden oft nur zu häufig verwendeten Kode angewendet. Manche Systeme machen keine Initiale Interpretierung, nur Kompilation (z.B.: RVM) 6.6 High-Performance Emulation Ziele: ‐ Programmoptimierung mit geringer Laufzeiterhöhung. Ausgleich der runtime optimization mit Programm Ausführung Verbesserung. ‐ Schnelle Objekt‐orientierte Programme 6.6.1 Optimization Framework Kompilation mit dynamic binary optimization (interpretation wird nicht ausgeführt). Profiling: Sammelt Daten mit Interpreter. Methoden werden optimiert. Graphs werden erstellt. Code reduction, restrukture und spezialisiert Kode. Runtime optimierung mit GC oder Heap Reorganisierung gemacht. 6.6.2 Optimization Code Relayout * Blöcke die oft aneinander ausgeführt warden (condition code) werden auch so in der Memory platziert. Diese Optimierung bringt die besten Ergebnisse. Method Inlining * Procedure Inlining (4.3.1). Kleinere Methoden (wenig parameters, stack, control) werden vorgezogen Calling sequence. Brauchen weniger cache. Können besser optimiert werden und werden ofter Ausgeführt. Gefahr ist code explosion bei grossere Methoden 3 Grossen und Ausführungshäufigkeit werden zuerst geprüft. Ausführungsfreqvenz: Call graph, mit Kante Profilierung. Ev. mit Stack frames Problem: Bau der Call-Graph und Profilierung (Daten Sammlung), backwords walk Optimizing Virtual Method Calls * Static and Virtual gehören als heufig ausgefürte code. Statische Profilierung der referenctype führt zum heufigkeitsbetimmung, welche Methode öfter ausgeführt wird. Guard (ist ein Kommand) vor inlined kode damit der Kode nur von heufigen Typ ausgeführt wird (isInstanceof). Branch in invokevirtual. PIC Polimorfic inline Prediction Technik für polimorfischen Methoden. Kode wird in Stub von von runtime sortiert. Multiversioning and Specialization Inlining, Invoke virtual, Guard. Lead zum spezialization: findet der einfachere Kode. Beispiel: Array[0]… On-Stack Replacement Stack ist zentral: Architected stack ist unterschiedlich von Implementation stack (werden Optimierungen, Spezialisierungen gemacht). On the fly Änderungen werden gemacht on-stack replacement (OSR) bei: 1. bei inlining, z.B: optimierung einer loop 2. Bie deferred implementierung: nach Gard muss neukompiliert werden. 3. Wenn debugger wird implementiert: man will Deoptimizieren um den echten Kode zu sehen. OSR modifiziert den Stack. Wie Checkpoint und live Point Extension kann der Compiler (dauerhafte) für OSR links (Points) zum Architekted Stack erstellen. 1. Extrahiert der architekted frame State 2. Generiert ein neues Implementierung Frame State der Konsistent mit dem neun Kode ist 3. Ersetzt der aktuelle Implementierung Frame State mit dem neuen Kleine Vorteilen, erlaubt Debugging und bei Deferred Compilation (keine Kompilierung für ungebrauchter Kode) erlaubt schnellere Start-up und kleinere Cache Optimization of Heap-Allocated Objects Heap allocation und Obj initialization wird inlined sein. Scalar replacement: ersetzt Objekt (wo übermässige verwendet) mit einem skalaren Wert (int). Muss eine escape Analysis gemacht werden, damit alle ref zum Object ersetzt werden. Dataflow analyseis: redundant access (zum Objecten) Low-Level Optimization Viele andere gültige optimierungen: Dead code remove, branch optimization, copy and constant paragon, straight reduction, code rescheduling. Array range and null reference checking range/null check + hemming anderen Fehlermeldungen Lösung: wird eine memory Addresse out of range für den Null Pointer erstellt. Exception und restore trotzdem werden gemacht. Solche Checks Kann man entfernen, hoisting ausserhalb der loop. Beispiel. r =a; p=a p null check nach r nullcheck kann man entfernen. Loop peeling: peeling der erste loop interation Optimizing Garbage Collection Bei Heap Initialisierung, ist Heap Zustand inkonsistent und der GC soll nicht Ausgeführt werden. Mit generationalem Kollektor, soll der Compiler fähig sein Schreibschutz zu garantieren. 6.7 Case Study: The Jikes Research Virtual Machine Kompilierung in native code, dann Optimierung (stages). Preemptive thread scheduling und gleichzeitige Applikation und runtime threads. Sampling bei Yeald point(?). Counter for called methods. Werden gemacht: Edge Profile, basic block profile, value profile. 4 Ästimation von Kompilierung in unterschiedlichen Niveau: Methode recompilierung time + executed execution time soll klein sein. Cost wachst linear zum Grösse der Kode. Instrumental profiling code. Level0: copy und constant propagation, common subexpression elimination, dead-code elimination, branch optimization. Trivial methode inilined. Code relayout, einfache lineare scan. Level1: High level code restructuring: aggressivere inlining, aggressivere code relayout Level3: Static single assignment (SSA) intermediate form (reg var nur einmal zugewiesen),loop unrolling (eliminiert loop closing branches) Start-up, steady-state (ist grosser als start-up, ist ein Durchschnitt von mehrere runs). Erste Optimierung wird gemacht beim eingegebenen level, andere in preformed baisis. AOS (Adaptive Optimization system) + FDP (Feedback Direction optimization) 6.8 Summary Nur Steady state ist langsam (VM+Support für OO) OO: robust und portable 5