아래 예제를 통해 IL 코드를 네이티브 CPU 명령어로 컴파일하는 방법을 설명하겠습니다.
public class Example
{
static void Main()
{
Console.WriteLine("Hey IL!!!");
}
}
주로 CLR은 형식에 대한 모든 세부 정보와 메타 데이터로 인해 해당 형식에서 호출되는 메서드를 알고 있습니다.
CLR이 네이티브 CPU 명령으로 IL을 실행하기 시작할 때 CLR은 Main의 코드에서 참조하는 모든 유형에 대해 내부 데이터 구조를 할당합니다.
우리의 경우에는 콘솔 유형이 하나만 있으므로 CLR은 하나의 내부 데이터 구조를 할당합니다. 내부 구조를 통해 참조 된 유형에 대한 액세스를 관리합니다.
해당 데이터 구조 내에서 CLR에는 해당 유형으로 정의 된 모든 메서드에 대한 항목이 있습니다. 각 항목에는 메소드의 구현을 찾을 수있는 주소가 있습니다.
이 구조를 초기화 할 때 CLR은 CLR 자체에 포함 된 문서화되지 않은 FUNCTION에 각 항목을 설정 합니다. 그리고 짐작할 수 있듯이이 FUNCTION 은 우리가 JIT 컴파일러라고 부르는 것입니다.
전반적으로 JIT 컴파일러는 IL을 네이티브 CPU 명령어로 컴파일하는 CLR 함수로 간주 할 수 있습니다. 이 과정이 우리의 예에서 어떻게 될지 자세히 보여 드리겠습니다.
1. Main이 WriteLine을 처음 호출하면 JITCompiler 함수가 호출됩니다.
2. JIT 컴파일러 함수는 호출되는 메서드와이 메서드를 정의하는 유형을 알고 있습니다.
3. Jit Compiler는 해당 유형이 정의 된 어셈블리를 검색하고 WriteLine 메소드의 IL 코드에서 해당 유형에 의해 정의 된 메소드에 대한 IL 코드를 가져옵니다.
4. JIT 컴파일러는 DYNAMIC 메모리 블록을 할당 한 후 JIT가 IL 코드를 네이티브 CPU 코드로 확인하고 컴파일하고 해당 CPU 코드를 해당 메모리 블록에 저장합니다.
5. 그런 다음 JIT 컴파일러는 내부 데이터 구조 항목으로 돌아가서 주소 (주로 WriteLine의 IL 코드 구현을 참조 함)를 WriteLine의 원시 CPU 명령을 포함하는 동적으로 생성 된 새 메모리 블록 주소로 대체합니다.
6. 마지막으로 JIT 컴파일러 함수는 메모리 블록의 코드로 이동하여 writeline 메서드의 네이티브 코드를 실행합니다.
7. WriteLine 실행 후 코드는 Mains '코드로 돌아가 정상적으로 실행을 계속합니다.