next up previous contents
Next: Implementierung der Speicherverwaltung Up: Techniken zur Programmausführung Previous: Diskussion   Inhalt


Zusammenfassung

Abbildung 3.8 zeigt die in Kapitel 2 eingeführte Grafik der 3 Hauptkomponente virtueller Maschinen, wobei hier einige Techniken und Aufgaben des dynamischen Compilers annotiert wurden.

Abbildung 3.8: Die drei Hauptkomponenten aus Sicht des dynamischen Compilers
\begin{figure}
\center{\epsfig{file=thebigpicture/threefold-compiler,width=10cm}}
\end{figure}

Viele der erwähnten Techniken zählen bereits zum Standardrepertoire einer modernen virtuellen Maschine. Inlining und inline caching sind bereits seit langem bekannt und sind in vielen Implementierungen realisiert. Dynamische Profile werden prinzipiell von jeder Maschine erhoben, die über einen dynamischen Compiler verfügt - diese beschränken sich jedoch häufig auf einfache Aufrufzähler.

Dabei ist eine leistungsfähige dynamische Profilgewinnung eine Schlüsselfunktionalität, die es dem dynamischen Compiler erlaubt, effizienteren Code zu erzeugen, als der statische. So ist es der der IBM Production-VM erstmals gelungen, mit dynamischer Compiler-Technologie den 1. Platz der Volano-Benchmarks [Volano, 2000] zu belegen und damit TowerJ als statischen Compiler zu verdrängen.

Die class hierarchy analysis stellt eine weitere fortgeschritten Technik dar, die im Zusammenhang mit Optimierungen wie dem Umwandeln von dynamische in statische Aufrufe und der Methodenintegration ohne Sicherungsinstruktion die Möglichkeit der Deoptimierung erforderlich macht.

Wie gezeigt wurde, ist die Technik der Deoptimierung zwar prinzipiell verstanden, sie trägt jedoch erheblich zu der Komplexität eines dynamischen Compilers bei. [Agesen and Detlefs, 1999a] berichten, daß eine großer Teil der Komplexität des SELF-Systems auf Deoptimierung und Reoptimierung zurürckzuführen ist.

Eine Technik, der in diesem Kapitel nur wenig Aufmerksamkeit geschenkt wurde, ist die Interpretation von Code. Zwar verfügen auch viele moderne Maschinen noch über einen Interpreter, Wie in Anhang A ersichtlich wird, zeichnet sich jedoch ein deutlicher Trend zu Systemen mit mehreren Compilern ab. Dabei kommt ein schneller, wenig optimierender Compiler an Stelle eines Interpreters zu Einsatz. Der so erzeugte Code, kann schneller ausgeführt werden als interpretierter Code, so daß sich der erhöhte Zeitaufwand für die Kompilation sehr schnell amortisiert.

Zu den Bereichen, in denen in der nächsten Zeit noch erhebliche Fortschritte zu erwarten sind, zählen die globalen Analysen. Eine weitreichende escape analysis ist bisher in keinem Produktionssystem zu finden. Algorithmen, die eine schnelle call graph construction ermöglichen, werden erforscht.

Weiterhin steigt durch die Eliminierung des Interpreters die Nachfrage nach schnellen Compiler-Algorithmen. Ein Beispiel stellt die linear register allocation dar, welche die mit quadratischer Komplexität arbeitenden graph coloring register allocation ersetzt. Der erzeugte Code ist in der Ausführung nur wenig langsamer, der Algorithmus aber erheblich schneller als der des komplexeren Pendants. Hier sind noch weitere schnelle Techniken zu erwarten, die ,,suboptimalen`` Code generieren.


next up previous contents
Next: Implementierung der Speicherverwaltung Up: Techniken zur Programmausführung Previous: Diskussion   Inhalt

2001-02-28