Я опишу компіляцію коду ІЛ у вбудовані інструкції процесора на прикладі нижче.
public class Example
{
static void Main()
{
Console.WriteLine("Hey IL!!!");
}
}
В першу чергу CLR знає всі подробиці про тип і про те, який метод, що викликається з цього типу, зумовлений метаданими.
Коли CLR починає виконувати IL у власній інструкції центрального процесора, тоді CLR виділяє внутрішні структури даних для кожного типу, на який посилається код Main.
У нашому випадку у нас є лише один тип консолі, тому CLR виділить одну внутрішню структуру даних через цю внутрішню структуру, ми будемо керувати доступом до вказаних типів
всередині цієї структури даних CLR містить записи про всі методи, визначені цим типом. Кожен запис містить адресу, де можна знайти реалізацію методу.
При ініціалізації цієї структури CLR встановлює кожен запис у недокументованій FUNCTION, що міститься всередині самого CLR. І, як ви можете здогадатися, ця FUNCTION - це те, що ми називаємо компілятором JIT.
Загалом, ви можете розглядати JIT-компілятор як функцію CLR, яка вводить ІЛ у власні інструкції процесора. Дозвольте мені докладно показати вам, як буде цей процес на нашому прикладі.
1. Коли Мейн робить свій перший дзвінок до WriteLine, викликається функція JITCompiler.
2. Функція компілятора JIT знає, який метод викликається, і який тип визначає цей метод.
Потім Jit Compiler здійснює пошук збірки, де визначено цей тип, і отримує код IL для методу, визначеного цим типом, у нашому випадку код IL методу WriteLine.
4. Компілятор JIT виділяє блок пам'яті DYNAMIC , після чого JIT перевіряє та компілює код IL у власний код процесора та зберігає цей код процесора в цьому блоці пам'яті.
5. Потім компілятор JIT повертається до внутрішнього запису структури даних і замінює адресу (яка в першу чергу посилається на реалізацію коду IL-запису WriteLine) новим адресно-динамічно створеним блоком пам'яті, який містить вбудовані вказівки процесора WriteLine.
6. Зрештою, функція компілятора JIT переходить до коду в блоці пам'яті. Цей код є реалізацією методу WriteLine.
7. Після реалізації WriteLine код повертається до головного коду, який продовжує виконуватись як зазвичай.