Runtime: Pregunta: llamada de interfaz y ASM generado

Creado en 28 nov. 2019  ·  3Comentarios  ·  Fuente: dotnet/runtime

¡Hola tios!

Tenga una aplicación muy simple, que llame a un método de interfaz 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);
        }
    }
}

Eso genera el siguiente ASM para 2.2 (para 3.0 hay lea rsp, [rbp] en lugar de agregar 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  

Perdón por las preguntas potencialmente muy tontas y novatos :) pero, ¿alguien podría darme una pista sobre:

1 ¿Por qué necesitamos la instrucción cmp aquí (no hay ningún salto condicional después del cmp)
2 ¿Qué es 7FFE7B410028h y por qué cargamos en r11 aquí?
3 ¿No es demasiado caro tener cmp por llamada de interfaz (¿podría cml en ese caso causar un error en la predicción de rama?)

¡Muchas gracias!

area-CodeGen-coreclr

Comentario más útil

¿Por qué necesitamos la instrucción cmp aquí (no hay ningún salto condicional después del cmp)

Activar un NullReferenceException en el punto de la llamada cuando this es null .

¿Qué es 7FFE7B410028h y por qué cargamos en r11 aquí?

La dirección de una "celda de indirección" que apunta a un código auxiliar que resuelve y llama al método de implementación de la interfaz. Desafortunadamente, la resolución de métodos de interfaz es una operación relativamente complicada que no se puede realizar "en línea".

Inicialmente apunta a https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28

Alguna documentación está disponible aquí (aunque no estoy seguro de si está actualizada)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md

Probablemente pueda ir directamente a https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs para obtener una descripción general rápida.

¿No es demasiado costoso tener cmp por llamada de interfaz (¿podría cml en ese caso causar un error en la predicción de rama?)

Es una instrucción de comparación, no una instrucción de rama condicional, por lo que no tiene nada que ver con la predicción de rama. Y es muy barato en comparación con el costo real de la llamada de interfaz.

Todos 3 comentarios

El cmp es una verificación nula temprana.
Puede leer sobre el envío de la interfaz aquí https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md

¿Por qué necesitamos la instrucción cmp aquí (no hay ningún salto condicional después del cmp)

Activar un NullReferenceException en el punto de la llamada cuando this es null .

¿Qué es 7FFE7B410028h y por qué cargamos en r11 aquí?

La dirección de una "celda de indirección" que apunta a un código auxiliar que resuelve y llama al método de implementación de la interfaz. Desafortunadamente, la resolución de métodos de interfaz es una operación relativamente complicada que no se puede realizar "en línea".

Inicialmente apunta a https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28

Alguna documentación está disponible aquí (aunque no estoy seguro de si está actualizada)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md

Probablemente pueda ir directamente a https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs para obtener una descripción general rápida.

¿No es demasiado costoso tener cmp por llamada de interfaz (¿podría cml en ese caso causar un error en la predicción de rama?)

Es una instrucción de comparación, no una instrucción de rama condicional, por lo que no tiene nada que ver con la predicción de rama. Y es muy barato en comparación con el costo real de la llamada de interfaz.

@mikedn @omariom Gracias

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

nalywa picture nalywa  ·  3Comentarios

btecu picture btecu  ·  3Comentarios

jamesqo picture jamesqo  ·  3Comentarios

bencz picture bencz  ·  3Comentarios

v0l picture v0l  ·  3Comentarios