Ответ 1
Мое предположение заключается в том, что если вы
хотитеизменить существующий аргумент, метод больше не может быть inlined?
Короткий ответ: Ваша догадка правильная (если этот комментарий к исходному коду по-прежнему правдивый сегодня).
// JIT today can't inline methods that contains "starg" opcode.
"JIT" - это часть среды выполнения .NET, которая переводит промежуточный язык (IL ) (например, "байт-код .NET" ) на ваш язык ассемблера. Только тогда код может быть выполнен на вашем компьютере. JIT выполняет этот метод перевода по методу и только тогда, когда это действительно необходимо: всякий раз, когда метод сначала вызывается, он сначала скомпилируется до фактического языка ассемблера "точно в срок" (JIT).
Компилятор С# не создает язык сборки для вашей компьютерной архитектуры сразу; вместо этого он генерирует промежуточный язык, который является своего рода языком ассемблера для абстрактной машины стека ( который был определен в ECMA 334 международный стандарт).
Например, присваивания параметра (в вашем примере: value
) будут переведены компилятором С# на команду IL, называемую starg
( "хранить аргумент" ).
В комментарии в основном говорится, что если метод содержал такое назначение (value = …
), тогда JIT в настоящее время не сможет "встроить" его. "Вложение метода" означает, что вместо генерации инструкций вызова к методу (т.е. ветки команд в другое местоположение кода), JIT вместо этого введет метод всего тела в том месте, где он вызывается. Обычно это делается для оптимизации скорости выполнения, потому что нет необходимости в ветвлении/прыжке, и, кроме того, я предполагаю, что новый фрейм стека тоже не должен быть установлен.
Вместо этого вместо локальной переменной (value_copy = …
) это ограничение JIT обойдется, потому что присвоения локальным переменным приводят к генерации другой команды IL: stloc
( "хранить локальную переменную" ).
См. также:
- Андрей Акиншин: "Рассказ о JIT-x86 inline и starg" (сообщение в блоге)