Runtime: Question : appel d'interface et ASM généré

Créé le 28 nov. 2019  ·  3Commentaires  ·  Source: dotnet/runtime

Salut les gars!

Avoir une application très simple, cette méthode d'interface d'appel comme celle-ci.

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

Cela génère l'ASM suivant pour 2.2 (pour 3.0 il y a lea rsp,[rbp] au lieu d'ajouter 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  

Désolé pour les questions potentiellement très stupides et novices :) mais quelqu'un pourrait-il me donner un indice sur :

1 Pourquoi avons-nous besoin d'instructions cmp ici (il n'y a pas de saut conditionnel après le cmp)
2 Qu'est-ce que 7FFE7B410028h et pourquoi nous chargeons en r11 ici
3 N'est-il pas trop coûteux d'avoir cmp par appel d'interface (cML pourrait-il dans ce cas faire échouer la prédiction de branche ?)

Merci beaucoup!

area-CodeGen-coreclr

Commentaire le plus utile

Pourquoi avons-nous besoin d'instructions cmp ici (il n'y a pas de saut conditionnel après le cmp)

Pour déclencher un NullReferenceException au point de l'appel lorsque this vaut null .

Qu'est-ce que 7FFE7B410028h et pourquoi nous chargeons en r11 ici

L'adresse d'une "cellule d'indirection" qui pointe vers un stub qui résout et appelle la méthode d'implémentation d'interface. Malheureusement, la résolution des méthodes d'interface est une opération relativement compliquée qui ne peut pas être effectuée "en ligne".

Initialement, il pointe vers https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28

De la documentation est disponible ici (bien que je ne sache pas à quel point elle est à jour)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md

Vous pouvez probablement passer directement à https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs pour obtenir un aperçu rapide.

N'est-il pas trop coûteux d'avoir cmp par appel d'interface (cML pourrait-il dans ce cas faire échouer la prédiction de branche ?)

C'est une instruction de comparaison, pas une instruction de branchement conditionnel, donc cela n'a rien à voir avec la prédiction de branchement. Et c'est très bon marché par rapport au coût réel de l'appel d'interface.

Tous les 3 commentaires

Le cmp est une vérification nulle anticipée.
Vous pouvez en savoir plus sur la répartition de l'interface ici https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md

Pourquoi avons-nous besoin d'instructions cmp ici (il n'y a pas de saut conditionnel après le cmp)

Pour déclencher un NullReferenceException au point de l'appel lorsque this vaut null .

Qu'est-ce que 7FFE7B410028h et pourquoi nous chargeons en r11 ici

L'adresse d'une "cellule d'indirection" qui pointe vers un stub qui résout et appelle la méthode d'implémentation d'interface. Malheureusement, la résolution des méthodes d'interface est une opération relativement compliquée qui ne peut pas être effectuée "en ligne".

Initialement, il pointe vers https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/coreclr/src/vm/amd64/VirtualCallStubAMD64.asm#L28

De la documentation est disponible ici (bien que je ne sache pas à quel point elle est à jour)
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md

Vous pouvez probablement passer directement à https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/virtual-stub-dispatch.md#stubs pour obtenir un aperçu rapide.

N'est-il pas trop coûteux d'avoir cmp par appel d'interface (cML pourrait-il dans ce cas faire échouer la prédiction de branche ?)

C'est une instruction de comparaison, pas une instruction de branchement conditionnel, donc cela n'a rien à voir avec la prédiction de branchement. Et c'est très bon marché par rapport au coût réel de l'appel d'interface.

@mikedn @omariom Merci

Cette page vous a été utile?
0 / 5 - 0 notes