Да, JIT-кодирование кода IL включает в себя перевод IL в машинные инструкции машинного кода.
Да, среда выполнения .NET взаимодействует с собственным машинным кодом JIT в том смысле, что среда выполнения владеет блоками памяти, занятыми собственным машинным кодом, вызовами среды выполнения в собственный машинный код и т. Д.
Вы правы, что среда выполнения .NET не интерпретирует код IL в ваших сборках.
Что происходит, когда выполнение достигает функции или блока кода (например, предложения else блока if), который еще не был JIT-скомпилирован в собственный машинный код, JIT'r вызывается для компиляции этого блока IL в собственный машинный код . Когда это будет сделано, выполнение программы вводит только что созданный машинный код для выполнения его программной логики. Если во время выполнения этого машинного кода выполнение достигает вызова функции для функции, которая еще не была скомпилирована в машинный код, JIT'r вызывается для компиляции этой функции «точно вовремя». И так далее.
JIT'r не обязательно компилирует сразу всю логику тела функции в машинный код. Если функция имеет операторы if, блоки операторов предложений if или else не могут быть JIT-скомпилированы до тех пор, пока выполнение не пройдет через этот блок. Неисполненные пути кода остаются в форме IL до тех пор, пока не будут выполнены.
Скомпилированный машинный код хранится в памяти, чтобы его можно было использовать снова при следующем выполнении этого раздела кода. Во второй раз, когда вы вызываете функцию, она будет работать быстрее, чем в первый раз, потому что во второй раз шаг JIT не требуется.
В настольной .NET машинный код хранится в памяти в течение всего времени существования домена приложения. В .NET CF собственный машинный код может быть отброшен, если приложению не хватает памяти. Он будет снова скомпилирован JIT из исходного кода IL, когда в следующий раз выполнение будет проходить через этот код.
Код «компилируется» на промежуточном языке Microsoft, который аналогичен формату сборки.
Когда вы дважды щелкаете исполняемый файл, загружается Windows,
mscoree.dll
которая затем настраивает среду CLR и запускает код вашей программы. Компилятор JIT начинает чтение кода MSIL в вашей программе и динамически компилирует код в инструкции x86, которые может выполнять ЦП.источник
.NET использует промежуточный язык под названием MSIL, иногда сокращенно IL. Компилятор читает ваш исходный код и выдает MSIL. Когда вы запускаете программу, компилятор .NET Just In Time (JIT) считывает ваш код MSIL и создает исполняемое приложение в памяти. Вы этого не увидите, но лучше знать, что происходит за кулисами.
источник
Я опишу компиляцию кода IL в инструкции собственного процессора на примере ниже.
public class Example { static void Main() { Console.WriteLine("Hey IL!!!"); } }
В первую очередь CLR знает все подробности о типе и о том, какой метод вызывается из этого типа, это связано с метаданными.
Когда CLR начинает выполнять IL в инструкции собственного процессора, в это время CLR выделяет внутренние структуры данных для каждого типа, на который ссылается код Main.
В нашем случае у нас есть только одна консоль типа, поэтому CLR будет выделять одну внутреннюю структуру данных через эту внутреннюю структуру, мы будем управлять доступом к ссылочным типам
внутри этой структуры данных CLR содержит записи обо всех методах, определенных этим типом. Каждая запись содержит адрес, по которому можно найти реализацию метода.
При инициализации этой структуры CLR устанавливает каждую запись в недокументированную ФУНКЦИЮ, содержащуюся внутри самой среды CLR. И, как вы можете догадаться, эта ФУНКЦИЯ - это то, что мы называем JIT-компилятором.
В целом вы можете рассматривать JIT-компилятор как функцию CLR, которая компилирует IL в собственные инструкции ЦП. Я подробно покажу вам, как этот процесс будет происходить на нашем примере.
1. Когда Main делает свой первый вызов WriteLine, вызывается функция JITCompiler.
2.Функция JIT Compiler знает, какой метод вызывается и какой тип определяет этот метод.
3. Затем Jit Compiler ищет сборку, в которой определен этот тип, и получает код IL для метода, определенного этим типом, в нашем случае код IL метода WriteLine.
4. JIT-компилятор выделяет ДИНАМИЧЕСКИЙ блок памяти, после этого JIT проверяет и компилирует код IL в собственный код ЦП и сохраняет этот код ЦП в этом блоке памяти.
5. Затем JIT-компилятор возвращается к записи внутренней структуры данных и заменяет адрес (который в основном относится к реализации кода IL для WriteLine) адресом нового динамически создаваемого блока памяти, который содержит собственные инструкции ЦП WriteLine.
6. Наконец, функция JIT-компилятора переходит к коду в блоке памяти. Этот код является реализацией метода WriteLine.
7. После реализации WriteLine код возвращается к коду Mains, который продолжает выполнение как обычно.
источник
.NET Framework использует среду CLR для создания MSIL (Microsoft Intermediate Language), также называемого IL. Компилятор считывает ваш исходный код и при сборке / компиляции проекта генерирует MSIL. Теперь, когда вы, наконец, запустите свой проект, в действие вступает .NET JIT ( Just-in-time Compiler ). JIT читает ваш код MSIL и создает собственный код (который является инструкциями x86), который может быть легко выполнен ЦП. JIT считывает все инструкции MSIL и выполняет их построчно.
Если вам интересно посмотреть, что происходит за кулисами, на это уже был дан ответ. Пожалуйста, следуйте - здесь
источник