Opiszę kompilację kodu IL do natywnych instrukcji CPU na przykładzie poniżej.
public class Example
{
static void Main()
{
Console.WriteLine("Hey IL!!!");
}
}
Przede wszystkim CLR zna wszystkie szczegóły dotyczące typu i metody wywoływanej z tego typu, co wynika z metadanych.
Gdy CLR zaczyna wykonywać IL w natywnej instrukcji procesora, CLR przydziela wewnętrzne struktury danych dla każdego typu, do którego odwołuje się kod Main.
W naszym przypadku mamy tylko jeden typ konsoli, więc CLR przydzieli jedną wewnętrzną strukturę danych poprzez tę wewnętrzną strukturę, będziemy zarządzać dostępem do przywoływanych typów
wewnątrz tej struktury danych CLR zawiera wpisy dotyczące wszystkich metod zdefiniowanych przez ten typ. Każdy wpis zawiera adres, pod którym można znaleźć implementację metody.
Podczas inicjowania tej struktury CLR ustawia każdy wpis w nieudokumentowanej FUNKCJI zawartej w samym CLR i, jak można się domyślić, ta FUNKCJA jest tym, co nazywamy JIT Compiler.
Ogólnie rzecz biorąc, można rozważyć JIT Compiler jako funkcję CLR, która kompiluje IL do natywnych instrukcji procesora. Pozwólcie, że pokażę wam szczegółowo, jak będzie wyglądał ten proces na naszym przykładzie.
1. Gdy Main wykonuje swoje pierwsze wywołanie WriteLine, wywoływana jest funkcja JITCompiler.
2. Funkcja kompilatora JIT wie, jaka metoda jest wywoływana i jaki typ definiuje tę metodę.
3. Następnie Jit Compiler przeszukuje zestaw, w którym zdefiniowano ten typ i pobiera kod IL dla metody zdefiniowanej przez ten typ w naszym przypadku kod IL metody WriteLine.
Kompilator JIT przydziela DYNAMICZNY blok pamięci, po czym JIT weryfikuje i kompiluje kod IL do natywnego kodu procesora i zapisuje ten kod procesora w tym bloku pamięci.
Następnie kompilator JIT wraca do wpisu wewnętrznej struktury danych i zastępuje adres (który odnosi się głównie do implementacji kodu IL w WriteLine) adresem nowym dynamicznie utworzonym blokiem pamięci, który zawiera natywne instrukcje CPU WriteLine.
Na koniec funkcja kompilatora JIT przeskakuje do kodu w bloku pamięci. Ten kod jest implementacją metody WriteLine.
7. Po zaimplementowaniu WriteLine, kod powraca do kodu Mains, który kontynuuje wykonywanie normalnie.