Runtime: Вопрос: вызов интерфейса и сгенерированный ASM

Созданный на 28 нояб. 2019  ·  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);
        }
    }
}

Это генерирует следующий ASM для 2.2 (для 3.0 вместо add 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 нет никакого условного перехода)

Чтобы вызвать NullReferenceException в точке вызова, когда this равно null .

Что такое 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 - это ранняя проверка на нулевое значение.
О диспетчеризации интерфейсов можно прочитать здесь https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md

Зачем здесь нужна инструкция cmp (после cmp нет никакого условного перехода)

Чтобы вызвать NullReferenceException в точке вызова, когда this равно null .

Что такое 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 рейтинги