Runtime: 質問:インターフェース呼び出しと生成されたASM

作成日 2019年11月28日  ·  3コメント  ·  ソース: dotnet/runtime

こんにちは、みんな!

このようなインターフェースメソッドを呼び出す非常にシンプルなアプリがあります。

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は分岐予測ミスを引き起こす可能性がありますか?)

本当にありがとうございました!

area-CodeGen-coreclr

最も参考になるコメント

ここでcmp命令が必要なのはなぜですか(cmpの後に条件付きジャンプはありません)

thisnull場合、呼び出しのポイントでNullReferenceExceptionをトリガーします。

7FFE7B410028hとは何ですか、またここでr11をロードする理由

インターフェイス実装メソッドを解決して呼び出すスタブを指す「間接セル」のアドレス。 残念ながら、インターフェイスメソッドの解決は比較的複雑な操作であり、「インライン」で実行することはできません。

最初は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に直接スキップして、概要をすばやく確認できます。

インターフェイス呼び出しごとにcmpを設定するのはコストがかかりすぎませんか(その場合、cmlは分岐予測ミスを引き起こす可能性がありますか?)

これは比較命令であり、条件付き分岐命令ではないため、分岐予測とは関係ありません。 そして、それは実際のインターフェース呼び出しコストと比較して非常に安いです。

全てのコメント3件

cmpは初期のnulllチェックです。
インターフェイスディスパッチについては、 https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.mdで読むことができます

ここでcmp命令が必要なのはなぜですか(cmpの後に条件付きジャンプはありません)

thisnull場合、呼び出しのポイントでNullReferenceExceptionをトリガーします。

7FFE7B410028hとは何ですか、またここでr11をロードする理由

インターフェイス実装メソッドを解決して呼び出すスタブを指す「間接セル」のアドレス。 残念ながら、インターフェイスメソッドの解決は比較的複雑な操作であり、「インライン」で実行することはできません。

最初は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に直接スキップして、概要をすばやく確認できます。

インターフェイス呼び出しごとにcmpを設定するのはコストがかかりすぎませんか(その場合、cmlは分岐予測ミスを引き起こす可能性がありますか?)

これは比較命令であり、条件付き分岐命令ではないため、分岐予測とは関係ありません。 そして、それは実際のインターフェース呼び出しコストと比較して非常に安いです。

@ mikedn @ omariomありがとう

このページは役に立ちましたか?
0 / 5 - 0 評価