Schlüssel Elemente


... [ Seminar Programmiersprachen und virtuelle Maschinen ] ... [ Google's V8 ] ... [ << Einführung ] ... [ Kürzliche Entwicklungen >> ] ...

Übersicht: Schlüssel Elemente


Speicher Modell der V8

Das Speicher Modell der V8 arbeitet mit 32 Bit tagged Pointer. Tagged Pointer werden in VMs häufig benutzt, um Zeiger zu kennzeichnen. In der V8 erfolgt dies direkt im Datenwort.
Außerdem bestehen die Datenworte 4 aligned Byte. Dadurch werden nur Vielfache von 4 als Adresse genutzt und somit sind die letzten 2 Bits frei zum taggen. 31 Bit vorzeichenbehaftete Integer werden in der V8 durch die Tags von Zeigern unterschieden.
Ein Integer sieht wie folgt aus: XXXX...XXX0. (X ist hierbei beliebig)
Ein Zeiger sieht dann so aus: XXXX....XX01.
Damit sind gerade Datenworte automatisch Integer und müssen nur noch um 1 Bit nach rechts geshiftet werden. Zeiger sind ungerade und werden noch mit 1 subtrahiert, um die tatsächliche Adresse zu erhalten. Dies bringt einen enormen Geschwindigkeitsvorteil.
In der V8 gibt es für jedes Objekt 3 Datenworte. Zunächst ein Zeiger auf eine Hidden Class, ein Zeiger auf Attribute die durch Namen wie 'x', 'y' und 'z' gekennzeichnet sind, sowie einen Zeiger auf Elemente, die durch Zahlen benannt sind. Für die letzten Beiden gibt es 2 Zustände. Im schnellen Fall zeigt der Zeiger auf ein Array, im Langsamen auf ein Dictionary bzw. eine Hashmap.
[ nach oben ]



Hidden Classes und Hidden Class Transitions

Das Ziel von Hidden Classes ist es JavaScript statisch und klassenbasiert, wie Java oder C++, zu realisieren. In Java oder C++ ist das Layout der Objekte zur Kompilezeit bekannt, Eigenschaften und Methoden können einfach referenziert werden, da sie immer an der gleichen Stelle gespeichert sind. Bei JavaScript gibt es keine Klassen und es muss immer ein dynamischer Lookup gemacht werden, der im Objekt und dessen Prototypen-Kette nach dem Attribut oder der Methode sucht.
Die Hidden Classes sollen nun die Möglichkeit geben, bekannte Techniken aus statisch, klassenbasierten Sprachen zu nutzen und Objekte mit gleicher Struktur zu gruppieren. Der Benutzer soll davon allerdings nichts merken.

Wie funktionieren Hidden Classes?

Zunächst einmal ein kleines Codestück:
    1 function Punkt(x, y){
    2   this.x = x;
    3   this.y = y;
    4 }
Für ein Punktobjekt gibt es nun immer 3 Datenworte. Zunächst ein Zeiger auf die initiale Klasse Class 0. Und 2 Zeiger für die Attribute des Objekts, die auf zwei kleine Speicherbereiche verweisen. (In diesem Fall nur der für die Attribute eingezeichnet)

Nach dem Ausführen von this.x = x entsteht eine Kopie der Class 0. Der Hidden Class Zeiger des Punktobjekts wird zudem auf diese Kopie Class 1 geändert. In dieser Class 1 wird der Offset für das x und im Speicherbereich des Punktobjekts an entsprechender Stelle gespeichert. Als letztes wird noch eine sogenannte "Hidden Class Transition" erzeugt, die von der Class 0 auf die Class 1 zeigt. Dieser Übergang wird benutzt, wenn ein Objekt auf die initiale Klasse zeigt und ein x-Attribut zum Objekt hinzugefügt wird.

Nun wird noch this.y = y ausgeführt. Hierdurch entsteht eine Kopie von Class 1. Auch der Hidden Class Zeiger wird auf diese Kopie Class 2 geändert. Der Offset in diesem Fall für y ist 1 und wird in der Hidden Class, sowie der enstprechende Wert im Speicherbereich des Objekts, gespeichert. Genau wie beim ersten Attribut wird wieder eine "Hidden Class Transition" auf die Class 2 erzeugt. In diesem Fall ist der Übergang von Class 1 nach Class 2, wenn dem Objekt ein y-Attribut hinzugefügt wird.

Abschließend

Würde ein zweites Objekt zunächst ein y-Attribut und dann ein x-Attribut hinzugefügt bekommen, entstehen 2 neue Hidden Classes, da die Zwischenstationen und Übergänge nicht denen des anderen Objekts ähneln.
Diese Technik bringt einen großen Geschwindigkeitsschub, da der Zugriff auf Attribute deutlich höher ist und nicht soviele Hidden Classes für gleiche Objekte erzeugt werden müssen. Gerade in einem Codeblock sind meißt Objekte mit identischer Struktur. Dadurch können nun Techniken aus statisch, klassenbasierten Sprachen genutzt werden.
[ nach oben ]



Generierung von nativem Maschinencode mit Inline Caching

In der V8 wird zunächst der komplette Code in nativen Maschinencode übersetzt. Zur Laufzeit werden dann die Zugriffe auf Attribute und Funktionsaufrufe durch Inline-Caching beschleunigt. Hierbei wird erstmal ein vollständiger Suchvorgang durchgeführt. Danach sind die Hidden Class und Ort von Attribut bzw. Methode bekannt. Darauf aufbauend generiert die V8 Maschinencode, der für zukünftige Objekte an gleicher Stelle im Code annimmt, dass sie dieselbe Hidden Class besitzen wie zuvor. Wenn dies der Fall ist, können die Eigenschaften direkt geladen werden, ohne einen langen Suchvorgang durchzuführen. Wenn die Annahme nicht zutrifft, wird der generierte Code entfernt und nach einem erneuten Suchvorgang durch ein neues Stück generierten Code ersetzt.
Dieser Vorgang erfolgt im monomorphen Zustand. Im megamorphen Zustand werden mehrere generierte Codestücke zur Hilfe genommen, mit dessen Hilfe die V8 schnell entscheiden kann, wo die Attribute und Methoden liegen.

Inline-Caching Zustände

[ nach oben ]



Speichermanagement System

Durch die Hidden Classes und das Inline Caching mit Generierung von Maschinencode ist die V8 bereits in der Lage schnellen Zugriff auf Attribute und Methoden zu gewähren. Sie soll aber auch in der Lage sein, von dem megamorphen Zustand wieder in den monomorphen Zustand zu gelangen. Dazu muss es möglich sein, generierte Codestücke wieder wegzuwerfen. Hier kommt der Garbage Collector der V8 zum Einsatz.
Der Garbage Collector (kurz GC) ist ein Garbage Collector.

2 Generationen

Garbage-Collection-Typen

[ nach oben ]


... [ Seminar Programmiersprachen und virtuelle Maschinen ] ... [ Google's V8 ] ... [ << Einführung ] ... [ Kürzliche Entwicklungen >> ] ... [ nach oben ] ...