Почему 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
?