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!
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
Commentaire le plus utile
Pour déclencher un
NullReferenceException
au point de l'appel lorsquethis
vautnull
.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.
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.