Was ist ein stack-map-frame
Ich habe seit kurzem Blick auf Die Java Virtual Machine Spezifikationen (JVMS) zu versuchen, besser zu verstehen, was macht meine Programme funktionieren, aber ich habe einen Abschnitt, ich bin mir nicht ganz bekommen...
Abschnitt 4.7.4 beschreibt die StackMapTable Attribut, und in diesem Abschnitt des Dokuments geht in die details über stack-map-frames. Das Problem ist, dass es ein wenig wortreich und ich lernen am besten durch Beispiel, nicht durch Lesen.
Ich verstehen, dass der erste stack-map-frame ist abgeleitet von der Methode, Deskriptor, aber ich verstehe nicht, wie (das ist angeblich erklärt hier.) Auch glaube ich nicht so ganz verstehen, was der stack map frames zu tun. Ich würde davon ausgehen, Sie sind ähnlich wie die Blöcke in Java, aber es scheint so, als ob du nicht stack-map-frames in jedem anderen.
Jedenfalls habe ich zwei konkrete Fragen:
- Was machen die stack-map-frames zu tun?
- Wie ist der erste stack-map-frame erstellt?
werden, und eine Allgemeine Frage:
- Kann jemand eine Erklärung weniger wortreich und einfacher zu verstehen als der in der JVM?
- Kann ich schlage vor, dass du über das I-learn-by-example Zeug und Lesen lernen Spezifikationen wie alle anderen auch.
- Es ist etwas, was ich arbeite. Das ist einer der Hauptgründe, warum ich beschlossen, Lesen Sie die JVMS in den ersten Platz.
- Ich habe auch gelesen das die JVM-spec, und glauben Sie mir, es ist nicht nur wie beim Lesen der spec, zum Beispiel: zu verstehen, wie die Typ-Verifizierung funktioniert (bezogen auf diese Frage), die Sie brauchen, um eine grundlegende Kenntnisse der Prolog-Programmierung... also ich denke, eine Frage/Antwort für diese lohnt sich in Stackoverflow
- Ich finde, dass es viel mehr hilfreich, um das ignorieren der Prolog Zeug und konzentrieren sich auf die klassische Inferenz verifier. Der neue Prüfer ist sehr ähnlich, Sie gerade beschlossen, geben Sie es in 200 Seiten Prolog, anstatt ein vauge Englisch Beschreibung wie das alte
- genau, das ist es, was diese Frage betrifft, zu übersetzen, um Deutsch die formale Spezifikation.
- Ich habe versucht, Ihnen zu erklären hier ausführlich volatileinterface.com/...
- da dieser link tot ist, ist es irgendwo sonst sein kann?
- web.archive.org/web/20170327123525/http://...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Java verlangt, dass alle Klassen, die geladen sind, um verifiziert zu werden, um die Sicherheit der sandbox und sicherzustellen, dass der code sicher ist, zu optimieren. Beachten Sie, dass dies erfolgt auf der bytecode-Ebene, also die überprüfung funktioniert nicht überprüfen Invarianten der Java Sprache, sondern lediglich überprüft, ob der bytecode macht Sinn, nach den Regeln für bytecode.
Unter anderem bytecode-Verifikation stellt sicher, dass die Anweisungen sind gut gebildet, dass Sie alle Sprünge zu gültigen Anweisungen innerhalb der Methode, und dass Sie alle Anweisungen zu betreiben, die auf Werten des entsprechenden Typs. Der Letzte ist wo der stack map kommt.
Die Sache ist, dass der bytecode selbst enthält keine expliziten Informationen. Arten bestimmt werden implizit durch die Datenfluss-Analyse. Zum Beispiel, eine Instruktion iconst erzeugt einen integer-Wert. Wenn Sie es speichern in slot 1, slot hat jetzt eine int. Wenn Ablaufsteuerung führt von code speichert eine float statt, der slot ist nun als ungültig, das heißt, Sie können nicht alles tun, mehr mit dem Wert, bis Sie überschrieben wird.
Historisch gesehen, ist der bytecode-verifier abgeleitet, alle Typen mit diesen Datenfluss Regeln. Es ist leider unmöglich, zu folgern, alle Typen in einer einzigen linearen Durchlauf durch den bytecode, da rückwärts springen könnte ungültig werden bereits inferred-Typen. Die klassische verifier lösten dieses Problem, indem die Iteration über den code, bis alles aufgehört änderung, die potenziell die mehrere Pässe.
Jedoch die Verifizierung macht das laden von Klassen, die langsam in Java. Oracle entschieden, um dieses Problem zu lösen, indem Sie eine neue, schnellere verifier,, die überprüfen können, bytecode in einem Arbeitsgang. Um dies zu tun, Sie erforderlich, alle neuen Klassen ab Java 7 (mit Java 6, die in einem übergangs-Zustand) zu transportieren Metadaten über Ihre Arten, so dass der bytecode verifiziert werden kann in einem einzigen Durchgang. Da der bytecode-format selbst nicht geändert werden kann, diese Art von Informationen gespeichert ist separat in einem Attribut namens
StackMapTable
.Einfach nur die Speicherung der Typ für jeden einzelnen Wert zu jedem einzelnen Punkt im code wären natürlich nehmen Sie viel Platz ein und werden sehr verschwenderisch. Um die Metadaten kleiner und effizienter, Sie beschloss, es zu haben Liste nur die Typen auf Positionen, die Ziele der Sprünge. Wenn Sie darüber nachdenken, dies ist die einzige Zeit, die Sie benötigen zusätzliche Informationen, um eine einzelne überprüfung bestehen. Zwischen Sprungziele alle control-flow-linear ist, so kann man Rückschlüsse auf die Arten an, die in zwischen-Positionen mit dem alten inferenzregeln.
Jeder position, wo Typen sind explizit aufgeführt ist, bekannt als ein stack-map-frame. Die
StackMapTable
- Attribut enthält eine Liste von frames in Ordnung, obwohl Sie in der Regel ausgedrückt als Differenz aus dem vorherigen frame, um zu reduzieren die Größe der Daten. Wenn es keine Bilder in der Methode, das Auftritt, wenn Ablaufsteuerung nie joins (also die CFG ist ein Baum), dann die StackMapTable Attribut kann weggelassen werden, vollständig.Dies ist also die grundlegende Idee, wie StackMapTable funktioniert und warum es Hinzugefügt wurde. Die Letzte Frage ist, wie die implizite ersten Rahmen erstellt. Die Antwort ist natürlich, dass am Anfang der Methode, der Operanden-stack leer ist und die lokale variable slots haben die Typen, die durch die Typen der Parameter der Methode, die abhängig von der Methode decriptor.
Wenn Sie ' re verwendet, um Java, es gibt ein paar kleinere Unterschiede auf, wie die Methode, die parameter-Typen arbeiten auf der bytecode-Ebene. First off, virtuelle Methoden haben eine implizite
this
als ersten parameter. Zweitensboolean
,byte
,char
, undshort
existieren nicht auf der bytecode-Ebene. Stattdessen, Sie sind alle implementiert, die als int-Werte hinter die kulissen.long
unddouble
Parameter wird, wie für alle lokalen Variablen, verbrauchen beiden lokalen Variablen im stack-frame.