Я опишу компиляцию кода 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, который продолжает выполнение как обычно.