こんにちは、みんな!
このようなインターフェースメソッドを呼び出す非常にシンプルなアプリがあります。
namespace InterfaceCalls
{
public interface IFoo
{
int Bar();
}
class Program
{
public static int M1(IFoo foo)
{
return foo.Bar();
}
static void Main(string[] args)
{
M1(null);
}
}
}
これにより、2.2用に次のASMが生成されます(3.0の場合、rsp、30hを追加する代わりにlea rsp、[rbp]があります)
return foo.Bar();
00007FFE7B521846 mov rcx,rsi
00007FFE7B521849 mov r11,7FFE7B410028h
00007FFE7B521853 cmp dword ptr [rcx],ecx
00007FFE7B521855 call qword ptr [7FFE7B410028h]
00007FFE7B52185B nop
00007FFE7B52185C add rsp,30h
00007FFE7B521860 pop rsi
00007FFE7B521861 ret
潜在的に非常に愚かで初心者の質問で申し訳ありません:)しかし誰かが私にヒントを教えてもらえますか:
1ここでcmp命令が必要なのはなぜですか(cmpの後に条件付きジャンプはありません)
2 7FFE7B410028hとは何ですか、また、ここでr11をロードする理由
3インターフェイス呼び出しごとにcmpを設定するのはコストがかかりすぎませんか(その場合、cmlは分岐予測ミスを引き起こす可能性がありますか?)
本当にありがとうございました!
cmpは初期のnulllチェックです。
インターフェイスディスパッチについては、 https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.mdで読むことができます
ここでcmp命令が必要なのはなぜですか(cmpの後に条件付きジャンプはありません)
this
がnull
場合、呼び出しのポイントでNullReferenceException
をトリガーします。
7FFE7B410028hとは何ですか、またここでr11をロードする理由
インターフェイス実装メソッドを解決して呼び出すスタブを指す「間接セル」のアドレス。 残念ながら、インターフェイスメソッドの解決は比較的複雑な操作であり、「インライン」で実行することはできません。
いくつかのドキュメントはここから入手できます(最新のものかどうかはわかりませんが)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md
おそらくhttps://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubsに直接スキップして、概要をすばやく確認できます。
インターフェイス呼び出しごとにcmpを設定するのはコストがかかりすぎませんか(その場合、cmlは分岐予測ミスを引き起こす可能性がありますか?)
これは比較命令であり、条件付き分岐命令ではないため、分岐予測とは関係ありません。 そして、それは実際のインターフェース呼び出しコストと比較して非常に安いです。
@ mikedn @ omariomありがとう
最も参考になるコメント
this
がnull
場合、呼び出しのポイントでNullReferenceException
をトリガーします。インターフェイス実装メソッドを解決して呼び出すスタブを指す「間接セル」のアドレス。 残念ながら、インターフェイスメソッドの解決は比較的複雑な操作であり、「インライン」で実行することはできません。
最初はhttps://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28を指し
いくつかのドキュメントはここから入手できます(最新のものかどうかはわかりませんが)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md
おそらくhttps://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubsに直接スキップして、概要をすばやく確認できます。
これは比較命令であり、条件付き分岐命令ではないため、分岐予測とは関係ありません。 そして、それは実際のインターフェース呼び出しコストと比較して非常に安いです。