質問

C ++には複数の継承があります。アセンブリレベルでの複数の継承の実装は非常に複雑になる可能性がありますが、良いことがあります 説明 これが通常どのように行われるか(vtables、ポインターの修正、サンクなど)についてオンライン。

Javaには複数の実装継承がありませんが、複数のインターフェイス継承があるため、クラスごとに単一のvtableを使用した単純な実装がそれを実装できるとは思いません。 Javaはインターフェイスを内部的にどのように実装しますか?

C ++に反して、JavaはJITコンパイルされているため、異なるコードが異なる方法で最適化される可能性があり、JVMが異なる場合が異なる場合があります。それでは、多くのJVMがこれについて続くいくつかの一般的な戦略がありますか、それとも特定のJVMでの実装を知っている人はいますか?

また、jvmsはしばしば偏見とインラインのメソッド呼び出しで、その場合はvtableまたは同等の関係がまったく存在しないため、仮想/インターフェイスメソッド呼び出しを実装する実際のアセンブリシーケンスについて尋ねるのは意味がないかもしれませんが、ほとんどのJVMはまだ一部を保持していると思いますそれらがすべてを敬birtすることができなかった場合、使用するクラスの一般的な表現のようなものです。この仮定は間違っていますか?この表現は、C ++ vtableのように何らかの形で見えますか?もしそうなら、インターフェイスには個別のvtableがあり、これらはクラスのvtableにどのようにリンクされていますか?もしそうなら、オブジェクトインスタンスには、C ++のオブジェクトインスタンスのような複数のvtableポインター(クラス/インターフェイスvtables)を持つことができますか?クラスタイプの参照と同じオブジェクトへのインターフェイスタイプは常に同じバイナリ値を持っていますか、それともポインターの修正が必要なC ++と同じように異なる可能性がありますか?

(参考のため: この質問 CLRについて似たようなことを尋ねると、良い説明があるようです このMSDNの記事 それは今では時代遅れかもしれませんが。 Javaに似たものを見つけることができませんでした。)

編集:

  • 「GCCコンパイラは、Javaクラスアレイリストがリストインターフェイスを実装する」という意味ではなく、「GCCコンパイラは整数追加 /関数呼び出し /などをどのように実装するか」という意味で「実装」します。
  • これがJVMバイトコードレベルでどのように機能するかを知っています。私が知りたいのは、JVMがクラスファイルをロードしてバイトコードをコンパイルした後にどのようなコードとデータストラクチャが生成されるかです。
役に立ちましたか?

解決

ホットスポットJVMの重要な機能はです インラインキャッシュ. 。これは、実際にはターゲットメソッドがインライン化されていることを意味するものではありませんが、仮想またはインターフェイスメソッドへのすべての将来の呼び出しがまったく同じ実装をターゲットにするというJITコードに仮定が配置されることを意味します(つまり、コールサイトが単極化されていること)。この場合、仮定が実際に保持されているかどうか(つまり、ターゲットオブジェクトのタイプが前回と同じかどうか)、および仮想テーブルなしでターゲットメソッドに直接コントロールを転送するかどうかにかかわらず、チェックがマシンコードにコンパイルされます。まったく関与しています。アサーションが失敗した場合、これを巨大なコールサイト(つまり、複数の可能なタイプを持つ)に変換する試みが行われる場合があります。これも失敗した場合(または最初の呼び出しである場合)、VTables(仮想方法用)およびItables(インターフェイス用)を使用して、定期的に長い見抜きが実行されます。

編集: : ホットスポットwiki VtableおよびItable Stubの詳細については、詳細があります。多型の場合、それは引き続きインラインキャッシュバージョンをコールサイトに入れます。ただし、コードは実際には、vtableまたはitableのルックアップを実行するスタブです。各vtableオフセット(0、1、2、...)に1つのvtableスタブがあります。 インターフェイスコール 与えられたオフセットでitable(見つかった場合)を調べる前に、無反応性の配列上に線形検索を追加します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top