Typ-Inferenz verwendet:
Spider hauptsächlich Inferenz verwendet Typ zu bestimmen, welche Eigenschaften zugegriffen wird; In Fällen, in denen Typinferenz nicht die genaue Form des Objekts findet, auf das zugegriffen wird, verwendet SpiderMonkey einen PIC (polymorphe Inline-Caches), um das Ergebnis der Suche zu speichern.
Eine weitere Form der Profilermittlung sind die polymorphen Inline-Caches des Baseline JIT. Polymorphe Inline-Caches sind eine klassische Technik zur Optimierung des dynamischen Versands, die aus der Smalltalk-Community stammt.
De-Optimierung ist der Name des Prozesses, was geschieht, wenn Typinferenz fehlschlägt:
Natürlich JavaScript eine dynamisch typisierte Sprache ist, ocassionally die Annahme über die versteckte Klasse des Objekts wird falsch, und in diesem Fall wird V8 "de-optimize" und kehrt zurück zur ursprünglichen Version des Methodenaufrufs, in dem die versteckte Klasse der Objekte überprüft wird.
Multiple Compiler ist notwendig, damit dies funktioniert:
Technisch bedeutet dies, dass der Compiler in der Tat zwei Compiler: eine Basis-Compiler und ein „Optimierungsprogramm“. (Oder noch mehr, wenn wir über JSC und SpiderMonkey sprechen). Das Konzept ist ziemlich solide und kann eine unglaubliche Leistung erbringen, aber es gibt eine Nuance: Der optimierte Code kann an verschiedenen Stellen "deoptimiert" werden, nicht nur am Eintrittspunkt, was bedeutet, dass die Umgebung (lokale Variablen, Argumente, Kontext) sein sollte kartiert und bewegt.
Da Ion der optimierende Compiler ist, unterstützt er das Kompilieren im Debug-Modus nicht. In der Tat ist die Implementierung einer solchen Unterstützung von zweifelhaftem Nutzen, da ihre Optimierungen im besten Fall zu unheilvollen Anrufungen führen würden. Um den Debug-Modus zu unterstützen, wird optimierter Code auf dem Stack optimiert und in Baseline gesichert. Das heißt, der Ionenrahmen auf dem Stapel wird mit einem rekonstruierten Grundlinienrahmen überschrieben, der der gleichen Stelle entspricht, an der der Ionenkode gerade ausgeführt wird.
Debugging wird über dynamische Deoptimierung getan:
wir besser machen können. Der Traum der 90er Jahre, verkörpert in der Sprache des Selbst, lebt in JavaScript. Wir können Self's dynamische Optimierung durch On-Stack-Austausch-Technik anpassen, um sogar optimierten Code zu debuggen. Die Kernidee von debug mode OSR
ist einfach: Wenn das Debuggen erforderlich ist, optimieren wir den JITed-Code auf dem Stack und kompilieren ihn neu, indem wir die Return-Adressen patchen, während wir fortfahren. Man könnte sagen, dass es fast elegant ist, wenn es nicht für die hohe Gewalt, die es auf Stapelrahmen ausübt, kommt.
Betrachten Sie die folgende JavaScript-Funktion:
function foo(o) { return o.f + o.g; }
In diesem Beispiel greift die Eigenschaft auf allem von einer einfachen Last von bekannten Orten in der Halde zu Anrufungen von Getter führen kann oder sogar komplizierte DOM-Traps, als wären o
ein Dokumentobjekt und f
der Name eines Elements auf der Seite. Das Baseline-JIT führt diese Eigenschaftszugriffe anfangs als vollständig polymorphe Verteilung aus. Aber während es dies tut, zeichnet es die Schritte auf, die es benötigt, und modifiziert dann die Heap-Zugriffe als Caches der notwendigen Schritte, um einen ähnlichen Zugriff in der Zukunft zu wiederholen. Wenn das Objekt beispielsweise eine Eigenschaft f
bei Offset 16 von der Basis des Objekts hat, wird der Code geändert, um zuerst schnell zu überprüfen, ob das eingehende Objekt aus einer Eigenschaft f
bei Offset 16 besteht, und dann die Last auszuführen. Diese Caches werden als inline bezeichnet, da sie vollständig als generierter Maschinencode dargestellt werden. Es wird gesagt, dass sie polymorph sind, da der Maschinencode modifiziert wird, wenn verschiedene Objektstrukturen angetroffen werden, um die zuvor angetroffenen Objekttypen einzuschalten, bevor eine vollständig dynamische Eigenschaftensuche durchgeführt wird. Wenn der DFG diesen Code kompiliert, wird er prüfen, ob der Inline-Cache monomorph ist - optimiert für nur eine Objektstruktur - und wenn ja, wird nur eine Überprüfung für diese Objektstruktur gefolgt von der direkten Belastung ausgegeben. Wenn in diesem Beispiel o immer ein Objekt mit den Eigenschaften f
und g
bei invarianten Offsets wäre, müsste das DFG nur eine Typprüfung für o
gefolgt von zwei direkten Lasten ausgeben.
Referenzen
Das klingt wie ein Rezept für eine Katastrophe. –