Runtime: Pergunta: chamada de interface e ASM gerado

Criado em 28 nov. 2019  ·  3Comentários  ·  Fonte: dotnet/runtime

Oi pessoal!

Tenha um aplicativo bem simples, que chame o método de interface como este.

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);
        }
    }
}

Isso gera o seguinte ASM para 2.2 (para 3.0 há lea rsp, [rbp] em vez de adicionar rsp, 30h)

            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  

Desculpe por perguntas potencialmente muito idiotas e novatas :) mas alguém poderia me dar uma dica sobre:

1 Por que precisamos da instrução cmp aqui (não há nenhum salto condicional após o cmp)
2 O que é 7FFE7B410028h e por que carregamos em r11 aqui
3 Não é muito caro ter cmp por chamada de interface (poderia cml, nesse caso, causar falha de previsão de ramificação?)

Muito obrigado!

area-CodeGen-coreclr

Comentários muito úteis

Por que precisamos da instrução cmp aqui (não há nenhum salto condicional após o cmp)

Para acionar NullReferenceException no ponto da chamada quando this é null .

O que é 7FFE7B410028h e por que carregamos em r11 aqui

O endereço de uma "célula indireta" que aponta para um esboço que resolve e chama o método de implementação da interface. Infelizmente, resolver métodos de interface é uma operação relativamente complicada que não pode ser feita "inline".

Inicialmente, ele aponta para https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28

Alguma documentação está disponível aqui (embora eu não tenha certeza de como ela está atualizada)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md

Você provavelmente pode pular direto para https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs para obter uma visão geral rápida.

Não é muito caro ter cmp por chamada de interface (poderia cml, nesse caso, causar falha de previsão de branch?)

É uma instrução de comparação, não uma instrução de desvio condicional, portanto, não tem nada a ver com a previsão de desvio. E é muito barato em comparação com o custo real da chamada da interface.

Todos 3 comentários

O cmp é uma verificação nula antecipada.
Você pode ler sobre o despacho de interface aqui https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md

Por que precisamos da instrução cmp aqui (não há nenhum salto condicional após o cmp)

Para acionar NullReferenceException no ponto da chamada quando this é null .

O que é 7FFE7B410028h e por que carregamos em r11 aqui

O endereço de uma "célula indireta" que aponta para um esboço que resolve e chama o método de implementação da interface. Infelizmente, resolver métodos de interface é uma operação relativamente complicada que não pode ser feita "inline".

Inicialmente, ele aponta para https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28

Alguma documentação está disponível aqui (embora eu não tenha certeza de como ela está atualizada)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md

Você provavelmente pode pular direto para https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs para obter uma visão geral rápida.

Não é muito caro ter cmp por chamada de interface (poderia cml, nesse caso, causar falha de previsão de branch?)

É uma instrução de comparação, não uma instrução de desvio condicional, portanto, não tem nada a ver com a previsão de desvio. E é muito barato em comparação com o custo real da chamada da interface.

@mikedn @omariom obrigado

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Timovzl picture Timovzl  ·  3Comentários

jkotas picture jkotas  ·  3Comentários

v0l picture v0l  ·  3Comentários

omajid picture omajid  ·  3Comentários

bencz picture bencz  ·  3Comentários