OCaml 編譯器 - 2021 年 5 月之前
大家好,
我很高興介紹第一期「OCaml 編譯器開發電子報」。我邀請了 OCaml 編譯器程式碼庫的頻繁貢獻者,簡短地寫下他們最近在做的事情,以便分享更多關於人們感興趣、正在關注和正在處理的事情的資訊。
這絕非詳盡無遺:很多人最終沒有時間寫東西,這也沒關係。但希望這能提供一個關於 OCaml 編譯器開發活動的小窗口,其結構與編譯器程式碼庫上無止盡的 Pull Requests 不同。
(這個倡議的靈感來自優秀的 Multicore 電子報。請不要期望它會像它一樣精緻或一致 :yo-yo:。)
注意
-
當然,歡迎隨時發表評論或提問,但我不知道寫簡短內容的人是否會關注此討論串,因此無法保證。
-
如果您一直在開發 OCaml 編譯器,並且想說些什麼,請隨意發文!如果您希望我在下次準備電子報時(未來某個隨機時間點)與您聯繫,請透過電子郵件 (gabriel.scherer at gmail) 告知我。
@dra27 (David Allsopp)
編譯器重新定位修補程式現在存在。還有一些需要編寫,並且需要拆分為可審閱的 PR,但核心功能正在運作。編譯器安裝可以複製到新的位置並且仍然可以運作,這表示 opam 中的本機切換理論上可以重新命名,更重要的是,我們可以在 opam 根目錄中快取先前建置的編譯器,以允許新的切換的編譯器為複本。這可能無法及時在 4.13 版本中審閱,儘管其目的是一旦合併,opam-repository 將會將回溯移植到較早的編譯器。
大量的腳本處理已導致一些可能的修補程式,以減少編譯器建置中腳本的使用,使其更接近於無。
FlexDLL 引導程式已完全翻新,大幅減少了建置時間。這將在 4.13 版本中 (#10135)
@nojb (Nicolás Ojeda Bär)
我正在開發 #10159,它會在 -output-complete-exe
二進位檔中啟用偵錯資訊。它在類 Unix 系統下使用 incbin,在 Windows 下使用其他方法。
@gasche (Gabriel Scherer)
我致力於將更多 PR 帶到決策階段(合併或關閉)。開啟的 PR 數量已從 220 個左右減少到 180 個,感覺不錯。
我也為 @Ekdohibs 的專案 camlboot 做出貢獻,這是一個 OCaml 的「免引導程式」實作,能夠編譯 OCaml 編譯器本身。由於各種原因,它目前以 OCaml 4.07 為目標。我們能夠完整建置 OCaml 編譯器,並檢查結果產生的引導二進位檔是否與上游引導程式一致。這給予了極大的信心,確信 OCaml 引導程式沒有「信任信任」攻擊。如需更多詳細資訊,請參閱我們的 草稿論文。
與 @Octachron (Florian Angeletti) 合作
我與 Florian Angeletti 合作,棄用某些命令列警告指定子序列,以避免 (4.12 版本中新增的) 警告名稱出現可用性問題。在之前,-w -partial-match
會停用警告 4,但 -w -partial
會被解讀為序列 w -p -w a -w r -w t -w i -w a -w l
,其中大部分會被忽略,但 -w a
會使所有警告靜音。現在,已棄用「未簽名」指定子 (-p
已簽名,a
未簽名) 的多字母序列。(我們首先棄用了所有未簽名指定子,但 Leo White 測試了結果並指出 -w A
很常見,因此現在我們只警告未簽名指定子的多字母序列。
我正與 @Octachron (Florian Angeletti) 合作,在遍歷模組簽章時對簽章項目進行分組。某些項目是「虛擬項目」,它們在道義上附加到「主要項目」中;程式碼大多忽略這一點,這會在邊角案例中產生各種錯誤。這是 Florian 在 2019 年 9 月使用 #8929 開始的工作,以修復簽章重新列印中的錯誤。我僅在 2020 年 5 月至 9 月開始審閱,我們決定進行相當大的變更,他在 2021 年 1 月將其拆分為幾個較小的變更,並在 2021 年 4 月合併。現在我們正在使用他的程式碼修正其他錯誤 (#9774, #10385)。就在本週,Florian 發布了一個很好的 PR,修正了多個與簽章項目分組相關的不同問題:#10401。
@xavierleroy (Xavier Leroy)
我修正了 #10339,一個在使用「Apple silicon」的新 Mac 上發生的神秘當機。這是由於 ARM (32 位元和 64 位元) 特定陣列邊界檢查最佳化所致,後端與平台無關的部分未將其納入考量,導致不正確的活動性分析和錯誤的暫存器配置。#10354 透過通知後端與平台無關的部分某些平台特定指令可能會引發錯誤來修正此問題。在過程中,它會重構在與平台相關的檔案中重複執行與平台無關的計算 (哪些指令是純粹的) 的類似程式碼。
我花了很多時間在 Inria 的 Jenkins 持續整合系統上,整合了一台新的 Mac Mini M1。由於不明原因,Jenkins 在 x86-64 模擬模式下執行了 CI 腳本,因此我們正在建置和測試 x86-64 版本的 OCaml,而不是預期的 ARM64 版本。經過一些腳本處理 (8b1bc01c3) 後,arm64-macos 已正確測試為我們 CI 的一部分。
目前,我正在閱讀 Sadiq Jaffer 的「安全點」提案 (#10039) 以及 Damien Doligez 在此基礎上提出的變更。這是邁向 Multicore OCaml 的必要步驟,因此我們確實需要在這方面取得進展。這是一項涉及新的靜態分析和每個程式碼發射器中多項調整的非平凡變更,但情況開始看起來不錯。
@mshinwell (Mark Shinwell)
我對安全點 PR (#10039) 進行了第一次審閱,並大幅簡化了建議的後端變更。我也參與了關於新的函式層級屬性的討論,如果函式主體內可能存在安全點 (包括配置) 時,該屬性會導致錯誤,以使目前假設此點穩定的程式碼更加可靠。這方面將在適當的時候提供一份設計文件。
我修正了在 RISC-V Inria CI 工作人員上發生的隨機區段錯誤 (#10349)。
在 Flambda 2 領域,我們花了兩個人天來偵錯與 Infix_tag 相關的問題!我們發現,如果任何根目錄都是封閉,則 OCaml 4.12 及更高版本中用於遍歷靜態資料 (“caml_globals”) 中 GC 根目錄的程式碼不正確。這部分是由於新的壓縮程式碼 (#9728) 具有隱藏的不變數:它不得多次看到靜態資料根目錄的任何欄位 (即使透過 Infix_tag)。據我們所知,這種情況在現有的編譯器中不會發生,儘管我們可能會提出修補程式以防止這種情況發生。它們會隨著 Flambda 2 的出現而發生,因為為了編譯靜態配置的不常數封閉 (其環境部分或全部在執行階段計算),我們會將封閉直接註冊為全域根目錄,以便稍後可以修補它們的環境。
@garrigue (Jacques Garrigue)
我一直在處理許多修正型別系統中錯誤的 PR,這些錯誤現在已合併
- #10277 修正了 GADT 型別推斷的主要理論錯誤 (#10383 僅適用於 -principal 模式)
- #10308 修正了模式中的本機開啟與引入存在型別變數的新語法之間的互動
- #10322 是一個內部變更,在回溯時於弱參考內使用正常參考;當回溯是不常使用的功能時,弱參考是一種最佳化,並且不再有用
- #10344 修正了延遲評估選擇性引數中的錯誤
- #10347 在加強通用變數作用域後,清理了統一演算法中的一些程式碼
- #10362 修正了型別檢查演算法中忘記的標準化
有些仍在進行中
- #10348 改善了在統一期間進行擴充的方式,以避免一些偽造的 GADT 相關歧義錯誤
- #10364 變更了模式比對案例主體的型別檢查,允許在某些非主要情況下發出警告;它還揭露了型別檢查器內部的許多與主要性相關的錯誤
最後,我與 Takafumi Saikawa (@t6s) 合作,透過確保在 #10337 中始終操作標準化的視圖,使型別的表示更接近其邏輯含義(大型變更,正在評估中)。
@let-def (Frédéric Bour)
一段時間以來,我一直在研究從 Menhir 剖析器產生錯誤訊息的新方法。
我最初的目標是偵測並產生 ‘let ;’ 情況的精確訊息
let x = 5;
let y = 6
let z = 7
LR 在第三個 ‘let’ 處偵測到錯誤,這在技術上是正確的,儘管我們希望將使用者指向 ‘;’,這可能是錯誤的根本原因。此目標已達成,但原型還遠未準備好用於生產環境。
提高錯誤上下文識別的表達能力和可維護性的主要概念是使用一種正規表達式。解析器的堆疊定義了一個句子形式的前綴。我們的正規表達式會與這個前綴進行匹配。自動機的內部細節不會洩漏(沒有對狀態的引用),正規語言僅由文法定義。透過適當的工具,可以從粗略的表達式開始,逐步細化到感興趣的案例,從而捕獲特定的情況。
現在,我專注於「錯誤訊息」開發流程中的一個特定點:提高「menhir --list-errors」的效率。這個命令用於列舉涵蓋所有錯誤情況(由 LR 文法定義)的句子。在我的電腦上,使用 OCaml 文法,它需要幾分鐘的時間和相當大的記憶體。早期結果令人鼓舞,我希望很快能為 Menhir 提交一個 PR。我們旨在實現的效能提升是讓該命令對於常見的文法來說幾乎能即時執行,並透過減少記憶體需求來處理更大的文法。例如,在 OCaml 的情況下,執行時間從 3 分鐘縮短到 2-3 秒,記憶體消耗從幾 GiB 降至 200 MiB。