インターフェイスメンバーへの仮想メソッド呼び出しの CLR 実装 質問する

インターフェイスメンバーへの仮想メソッド呼び出しの CLR 実装 質問する

好奇心から:CLR はどのようにして仮想メソッド呼び出しをインターフェイス メンバーに正しい実装にディスパッチするのでしょうか?

CLR が各メソッドのメソッド スロットを持つ各型に対して維持する VTable について、また各インターフェイスに対して、関連するインターフェイス メソッドの実装を指す追加のメソッド スロット リストがあることについては知っています。しかし、次の点が理解できません。CLR はどのようにして、型の VTable からどのインターフェイス メソッド スロット リストを選択するかを効率的に決定するのでしょうか。

記事.NET Framework の内部を詳しく調べて、CLR がランタイム オブジェクトを作成する方法を理解するMSDN マガジン 2005 年 5 月号では、インターフェイス ID でインデックス付けされたプロセス レベルのマッピング テーブル IVMap について説明しています。これは、同じプロセス内のすべての型が同じ IVMap への同じポインターを持つことを意味しますか?

また、次のようにも述べています。

2 つのクラスによって実装されている場合MyInterface1、IVMap テーブルには 2 つのエントリがあります。エントリは、メソッド テーブル内に埋め込まれたサブテーブルの先頭を指しますMyClass

CLR はどのエントリを選択するかをどのように知るのでしょうか? 現在のタイプに一致するエントリを見つけるために線形検索を実行しますか? または、バイナリ検索を実行しますか? あるいは、何らかの直接インデックスを作成し、その中に多くの空のエントリが含まれる可能性があるマップを作成しますか?

私はC#第3版のCLRのインターフェイスの章も読みましたが、このことについては触れられていません。したがって、この他の質問私の質問に答えないでください。

ベストアンサー1

その記事は10年以上前のもので、たくさんそれ以来変化しました。

IVMapsは現在、仮想スタブディスパッチ

仮想スタブ ディスパッチ (VSD) は、従来の仮想メソッド テーブルの代わりに仮想メソッド呼び出しにスタブを使用する手法です。 以前は、インターフェイス ディスパッチでは、インターフェイスにプロセス固有の識別子が必要であり、ロードされたすべてのインターフェイスがグローバル インターフェイス仮想テーブル マップに追加される必要がありました。

この記事を読んでください。そこにはあなたが知る必要のあるより詳しい情報が載っています。ランタイムの書これはもともと CLR 開発者が CLR 開発者向けに書いたドキュメントでしたが、現在は誰でも利用できるように公開されています。基本的にはランタイムの中身について説明しています。

ここで記事を繰り返す意味はありませんが、要点とその意味を述べたいと思います。

  • JITはインターフェースメンバーの呼び出しを見つけると、それをコンパイルしてルックアップスタブこれは、汎用リゾルバ
  • 汎用リゾルバは、どのメソッドを呼び出すかを調べる関数です。これは、このようなメソッドを呼び出す最も一般的な方法であり、したがって最も遅い方法です。ルックアップスタブ、そのスタブをパッチ(実行時にコードを書き換える)して、ディスパッチスタブまた、スタブを解決する後で使用するためにルックアップスタブこの時点で消えます。
  • ディスパッチスタブインターフェースメンバーを呼び出す最も速い方法ですが、注意点があります。呼び出しが単形的な、つまり、インターフェース呼び出しが常に同じ具体的な型に解決される場合に最適化されています。オブジェクトのメソッドテーブル(つまり具体的な型)を、以前に見たもの(スタブにハードコードされている)と比較し、比較が成功した場合はキャッシュされたメソッド(アドレスもハードコードされている)を呼び出します。失敗した場合は、スタブを解決する
  • スタブを解決する多態的な呼び出し(一般的なケース)を処理します。どのメソッドを呼び出すかを見つけるためにキャッシュを使用します。メソッドがキャッシュにない場合は、汎用リゾルバ(このキャッシュにも書き込みます)。

そして、この記事から引用した重要な考慮事項は次のとおりです。

ディスパッチ スタブが頻繁に失敗すると、呼び出しサイトはポリモーフィックであるとみなされ、解決スタブは呼び出しサイトをバックパッチして解決スタブを直接ポイントし、ディスパッチ スタブが常に失敗するオーバーヘッドを回避します。同期ポイント (現在は GC の終了) では、呼び出しサイトのポリモーフィック属性は通常一時的であるという仮定の下、ポリモーフィック サイトはランダムにモノモーフィック呼び出しサイトに昇格されます。この仮定が特定の呼び出しサイトで正しくない場合は、すぐにバックパッチがトリガーされ、再びポリモーフィックに降格されます。

実行時間は本当に楽観的モノモーフィックな呼び出しサイトについて、実際のコードでは非常に意味があり、回避しようとしますスタブを解決するできるだけ。

おすすめ記事