Почему JIT-компилятор .NET решил не встроить или не оптимизировать вызовы пустых статических методов, которые не имеют побочных эффектов?

Я думаю, что я наблюдаю, что компилятор .NET JIT не встраивает и не оптимизирует вызовы пустых статических методов, которые не имеют побочных эффектов, что немного удивительно, учитывая некоторые заказные онлайн-ресурсы.

Моя среда - Visual Studio 2013 на платформе x64, Windows 8.1, .NET Framework 4.5.

Учитывая эту простую тестовую программу (https://ideone.com/2BRCpC)

class Program
{
    static void EmptyBody()
    {
    }

    static void Main()
    {
        EmptyBody();
    }
}

Сборка релиза с оптимизацией вышеуказанной программы производит следующий MSIL дляMain а такжеEmptyBody:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  call       void Program::EmptyBody()
  IL_0005:  ret
} // end of method Program::Main

.method private hidebysig static void  EmptyBody() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method Program::EmptyBody

Не удивительно, что MSIL содержит звонок отMain вEmptyBody, поскольку компилятор C # не должен встроить или оптимизировать вызовы, подобные этому. Однако я подумал, что JIT-компилятор затем встроит или оптимизирует этот вызов. Но этого не происходит.

Если я запускаю вышеупомянутую программу и врываюсь в отладчик вMainсгенерированная сборка такая:

00572621  mov         ebp,esp  
00572623  cmp         dword ptr ds:[4320B84h],0  
0057262A  je          00572631  
0057262C  call        73E6AF20  
00572631  call        dword ptr ds:[4321578h]  

Указатель инструкции сразу устанавливается на последнюю строку в 00572631, которая является вызовомEmptyBody, Шагая вEmptyBodyсгенерированная сборка

00BD2651  mov         ebp,esp  
00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  
00BD2661  nop  
00BD2662  pop         ebp  
00BD2663  ret

Указатель инструкции сразу устанавливается наnop линия на 00BD2661, которая ничего не делает, и я не могу догадаться, почему она генерируется в первую очередь.

Учитывая, что два приведенных выше фрагмента сборки имеют один и тот же заголовок из 4 инструкций, я предполагаю, что это просто обычная схема ввода метода, где установлен стек и тому подобное. Я стремлюсь узнать, что будут делать эти повторяющиеся инструкции:

00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  

В любом случае, главный вопрос: почему JIT-компилятор создает сборку, которая вызывает статический метод с пустым теломEmptyBody?

Ответы на вопрос(1)

Ваш ответ на вопрос