Khi subset compiler đã đủ mạnh, ngày trọng đại nhất của dự án đã đến: thực hiện nghi lễ bootstrap fixed-point. Đây là lúc chúng tôi kiểm chứng xem trình biên dịch mới có thể tự biên dịch chính nó và tạo ra các thế hệ trình biên dịch ổn định hay không.
Sprint 91 đến 94 thiết lập chuỗi bootstrap này thông qua hai script: bootstrap-stage1.sh và bootstrap-fixed-point.sh.
Quy trình bootstrap hoạt động theo các thế hệ (stages):
- Stage 0: Trình biên dịch gốc viết bằng JavaScript (duyc.js).
- Stage 1: Trình biên dịch viết bằng DUY, được biên dịch bởi Stage 0. Đây là trình biên dịch native đầu tiên nhưng được sinh ra từ JS.
- Stage 2: Trình biên dịch viết bằng DUY, được biên dịch bởi Stage 1. Đây là trình biên dịch native được sinh ra bởi một trình biên dịch native.
graph TD
A[Mã nguồn compiler viết bằng DUY] -->|Biên dịch bằng| B[JS Oracle Compiler Stage 0 trên Node.js]
B -->|Sinh ra| C[Native Compiler Stage 1 Binary]
A -->|Biên dịch bằng| C
C -->|Sinh ra| D[Native Compiler Stage 2 Binary]
D -->|Tự biên dịch chính mình| E[Stage 3 Binary]
D -->|So sánh SHA-256| F{Fixed-Point Match?}
E -->|So sánh SHA-256| F
F -->|Yes - Đạt điểm cân bằng tĩnh| G[Bootstrap thành công]
F -->|No - Lỗi suy thoái sinh mã| H[Regression - Sửa đổi compiler]
Nhiệm vụ tối cao của fixed-point bootstrap là: Stage 1 and Stage 2 phải giống nhau tuyệt đối. Nếu chúng ta dùng Stage 1 và Stage 2 để dịch cùng một file compiler source, hai file nhị phân đầu ra phải trùng khớp nhau đến từng byte (hash report trùng khớp).
Nếu hash bị lệch dù chỉ một bit, nghĩa là trình biên dịch đang sinh mã có lỗi không xác định, hoặc hành vi biên dịch bị trôi (compiler drift) qua các thế hệ. Lễ rửa tội bằng lửa này bắt chúng tôi phải chạy lặp đi lặp lại chuỗi script để tìm ra lỗi trôi compiler, sửa từng dòng code trong checker để đạt được điểm cân bằng tĩnh.
Tôi nhớ lần chạy bootstrap đầu tiên, mã hash SHA-256 bị lệch hoàn toàn. Lòng tôi trĩu nặng. Tôi phải dump toàn bộ file asm của Stage 1 và Stage 2 ra để so sánh từng dòng lệnh. Hóa ra, compiler của tôi khi phân giải symbol đã duyệt qua các file nguồn theo thứ tự không xác định của hệ thống file, dẫn đến việc thứ tự các hàm trong file object bị hoán đổi. Sau khi sửa lỗi sort file trong resolver, chạy lại script và thấy hai mã hash trùng khớp hoàn hảo, cảm xúc lúc đó thật khó tả. Compiler đã chính thức đạt điểm cân bằng tĩnh.
Bình luận (0)
Đang tải bình luận...