2010-12-12 9 views
36

C++ hat mehrere Vererbung. Die Implementierung der Mehrfachvererbung auf der Assembly-Ebene kann ziemlich kompliziert sein, aber es gibt gute descriptions online wie dies normalerweise getan wird (VTables, Zeiger-Fixups, Thunks, etc.).Wie werden Java-Schnittstellen intern implementiert? (VTabellen?)

Java verfügt nicht über mehrere Implementationsvererbung, aber es hat mehrere Schnittstellenvererbung, also glaube ich nicht, dass eine einfache Implementierung mit einer einzelnen vtable pro Klasse das implementieren kann. Wie implementiert Java Schnittstellen intern?

Ich weiß, dass Java im Gegensatz zu C++ Jit kompiliert wird, so dass verschiedene Teile des Codes möglicherweise anders optimiert werden, und verschiedene JVMs könnten die Dinge anders machen. Gibt es also eine allgemeine Strategie, der viele JVMs folgen, oder kennt jemand die Implementierung in einer bestimmten JVM?

Auch JVMs oft Devirtualize und Inline-Methodenaufrufe in diesem Fall gibt es überhaupt keine Vtables oder gleichwertige beteiligt, so dass es nicht sinnvoll ist, nach tatsächlichen Assembly-Sequenzen zu fragen, die virtuelle/Interface-Methodenaufrufe implementieren, aber ich nehme das am meisten an JVMs behalten immer noch eine Art allgemeine Repräsentation von Klassen, um sie zu benutzen, wenn sie nicht in der Lage waren, alles zu devirtualisieren. Ist diese Annahme falsch? Ist diese Darstellung in etwa wie eine C++ vtable? Wenn ja, haben Interfaces separate VTables und wie sind diese mit Klassenvtabellen verbunden? Wenn dies der Fall ist, können Objektinstanzen mehrere vtable-Zeiger (auf Klassen-/Schnittstellen-Vtabellen) wie Objekt-Instanzen in C++ haben? Haben Verweise eines Klassentyps und eines Schnittstellentyps auf dasselbe Objekt immer den gleichen binären Wert oder können sich diese wie in C++ unterscheiden, wo sie Zeigerkorrekturen benötigen?

(Referenz: this question fragt etwas Ähnliches über die CLR, und es erscheint in this msdn article eine gute Erklärung zu sein, obwohl das inzwischen veraltet sein kann ich nicht in der Lage für Java etwas Ähnliches zu finden..)

Edit:

  • I ‚Geräte‘ im Sinne bedeuten, nicht im Sinne von „Java-Klasse Arraylist implementiert die Liste Schnittstelle„Wie funktioniert der GCC-Compiler integer-Addition/Funktionsaufrufe/etc implementieren“ ".
  • Ich weiß, wie das auf der JVM-Bytecodeebene funktioniert, was ich wissen möchte ist, welche Art von Code und Datenstrukturen die JVM generiert, nachdem sie die Klassendateien geladen und den Bytecode kompiliert hat.
+2

Sie erwähnen Schnittstellenvererbung und Implementierungsvererbung. Implementierungsvererbung ist schwierig, da Sie eine definierte Suchreihenfolge haben müssen. Die Schnittstellenvererbung ist viel einfacher. Sie haben nur eine Karte mit allen Methodensignaturen, die implementiert werden müssen. Es ist keine Suchreihenfolge erforderlich (da keine Implementierung angehängt ist). Dort ist keine Reihenfolge. – extraneon

Antwort

25

Das Hauptmerkmal des HotSpot JVM ist inline caching. Dies bedeutet nicht, dass die Zielmethode inline ist, sondern bedeutet, dass eine Annahme in den JIT-Code eingegeben wird, dass jeder zukünftige Aufruf der virtuellen oder Schnittstellenmethode dieselbe Implementierung anvisiert (dh die Aufrufseite ist) monomorph). In diesem Fall wird in den Maschinencode eine Prüfung eingecheckt, ob die Annahme tatsächlich vorliegt (dh ob der Typ des Zielobjekts das gleiche wie beim letzten Mal ist) und dann die Steuerung direkt an die Zielmethode - mit übergeben überhaupt keine virtuellen Tabellen beteiligt. Wenn die Assertion fehlschlägt, kann ein Versuch unternommen werden, dies in eine megamorphe Call-Site umzuwandeln (d. H. Mit mehreren möglichen Typen); Wenn dies ebenfalls fehlschlägt (oder wenn es sich um den ersten Aufruf handelt), wird eine regelmäßige, langatmige Suche durchgeführt, wobei vtables (für virtuelle Methoden) und ip (für Schnittstellen) verwendet wird.

bearbeiten: Die Hotspot Wiki hat weitere Einzelheiten über die VTable und ITable Stubs.Im polymorphen Fall wird immer noch eine Inline-Cache-Version in die Aufruf-Site eingefügt. Der Code ist jedoch tatsächlich ein Stub, der eine Suche in einer Vtable oder einem iable ausführt. Es gibt einen Vtable-Stub für jeden Vtable-Offset (0, 1, 2, ...). Interface calls Fügen Sie eine lineare Suche über ein Array von Itables hinzu, bevor Sie das itituable (falls gefunden) am angegebenen Offset betrachten.

+0

Die Hotspot Wiki Seiten auf VirtualCalls und InterfaceCalls scheinen genau das zu sein, wonach ich gesucht habe. Trotzdem müssen sie herumkommen, um alles zu lesen. – JanKanis

+1

Das Wiki wurde nach https://wikis.oracle.com/display/HotSpotInternals/Home verschoben –

+0

Das Oracle-Wiki wurde eingefroren, ich denke, https://wiki.openjdk.java.net/display/HotSpot/Main ist wo die aktualisierbaren Informationen gelandet sind. – JanKanis