Tôi sẽ mô tả việc biên dịch mã IL thành các hướng dẫn CPU gốc qua ví dụ bên dưới.
public class Example
{
static void Main()
{
Console.WriteLine("Hey IL!!!");
}
}
Về cơ bản CLR biết mọi chi tiết về kiểu và phương thức nào được gọi từ kiểu đó, điều này là do siêu dữ liệu.
Khi CLR bắt đầu thực thi IL thành lệnh CPU gốc thì lúc đó CLR phân bổ cấu trúc dữ liệu bên trong cho mọi kiểu được tham chiếu bởi mã của Main.
Trong trường hợp của chúng tôi, chúng tôi chỉ có một loại Console do đó CLR sẽ cấp phát một cấu trúc dữ liệu nội bộ thông qua cấu trúc bên trong đó, chúng tôi sẽ cấp quyền truy cập vào các loại được tham chiếu
bên trong cấu trúc dữ liệu CLR có các mục nhập về tất cả các phương thức được định nghĩa bởi kiểu đó. Mỗi mục nhập giữ địa chỉ nơi có thể tìm thấy phương thức triển khai.
Khi khởi tạo cấu trúc này CLR đặt mỗi mục nhập trong FUNCTION không có tài liệu chứa bên trong chính CLR Và như bạn có thể đoán FUNCTION này là cái mà chúng ta gọi là JIT Compiler.
Nhìn chung, bạn có thể coi Trình biên dịch JIT như một hàm CLR để biên dịch IL thành các lệnh CPU gốc. Hãy để tôi cho bạn thấy chi tiết quá trình này sẽ như thế nào trong ví dụ của chúng tôi.
1.Khi Main thực hiện lệnh gọi đầu tiên tới WriteLine, hàm JITCompiler được gọi.
Hàm 2.JIT Compiler biết phương thức nào đang được gọi và kiểu nào xác định phương thức này.
3.Sau đó, Trình biên dịch Jit tìm kiếm hợp ngữ đã định nghĩa kiểu đó và lấy mã IL cho phương thức được định nghĩa bởi kiểu đó trong trường hợp mã IL của phương thức WriteLine.
Trình biên dịch 4.JIT phân bổ khối bộ nhớ DYNAMIC , sau đó JIT xác minh và biên dịch mã IL thành mã CPU gốc và lưu mã CPU đó trong khối bộ nhớ đó.
5. Sau đó, trình biên dịch JIT quay trở lại mục nhập cấu trúc dữ liệu bên trong và thay thế địa chỉ (chủ yếu tham chiếu đến việc triển khai mã IL của WriteLine) bằng địa chỉ khối bộ nhớ được tạo động mới có chứa các lệnh CPU gốc của WriteLine.
6.Cuối cùng, hàm JIT Compiler nhảy đến mã trong khối bộ nhớ. Đoạn mã này là sự triển khai của phương thức WriteLine.
7.Sau khi thực hiện WriteLine, mã trở về Mains'code và tiếp tục thực thi như bình thường.