Tập 86: Resource protocol — Kỷ luật giải phóng tài nguyên tĩnh

Trạng thái sự thật: Đang diễn ra — Nhật ký chiến dịch đang nóng tại Sprint 147.

Chúng tôi đang đứng trước một trong những gate quan trọng nhất của ngôn ngữ lập trình hệ thống không có GC: đảm bảo tài nguyên (file handle, socket, memory block) được giải phóng một cách deterministic (định tính) ngay khi ra khỏi scope mà không phụ thuộc vào sự tự giác của lập trình viên. Giải pháp của DUY là Resource Protocol, xoay quanh phương thức hủy tài nguyên (drop).

Khác với Rust sử dụng hệ thống borrow checker cực kỳ phức tạp dựa trên các tham số lifetime tĩnh để chứng minh bộ nhớ an toàn ở mọi điểm, DUY chọn con đường đơn giản và thực tiễn hơn: kết hợp owned[T], view[T]region. Khi một kiểu dữ liệu tự trị (owned) ra khỏi tầm vực (scope), compiler sẽ tự động chèn lời gọi drop tĩnh cho nó.

Thử thách hiện tại trên bàn làm việc của tôi ở Sprint 147 là xử lý lỗi giải phóng hai lần (double-drop) và lỗi sử dụng sau khi giải phóng (use-after-free) trong các nhánh rẽ điều khiển phức tạp (như if-else hoặc match). Nếu một biến bị di chuyển (move) vào một hàm khác, compiler phải đánh dấu trạng thái của nó là "tĩnh đã di chuyển" và cấm chèn lời gọi drop ở cuối block hiện tại.

Tôi nhớ buổi tối gỡ lỗi escape checking cho view. Compiler liên tục báo lỗi false positive khi tôi trả về một view hợp lệ từ một struct nằm trên stack. Cảm giác lúc đó rất bực mình, tôi đã tự hỏi liệu mô hình memory của mình có quá cứng nhắc hay không. Nhưng khi tôi kiên nhẫn viết thêm thuật toán phân tích luồng dữ liệu (data-flow analysis) thô để theo dõi trạng thái di chuyển của biến qua từng basic block, native checker đã trở nên thông minh hơn, phân biệt chính xác đâu là mượn hợp lệ và đâu là rò rỉ thực sự. Mã nguồn native checker cho phần này đang được hardening để chuẩn bị đẩy sang backend LLVM.


Bình luận (0)

Đang tải bình luận...