我在閱讀「不合作環境中的垃圾收集器」一文,並想知道實施它會有多困難。該論文描述了從處理器收集所有地址的需求(除堆棧外)。堆棧部分看起來很直觀。除了在彙編中明確列舉每個寄存器之外,是否有任何方法可以從寄存器中收集地址?假設x86_64位於類似POSIX的系統上,例如linux或mac。Boehm Weiser垃圾收集器的機制
的setjmp
我在閱讀「不合作環境中的垃圾收集器」一文,並想知道實施它會有多困難。該論文描述了從處理器收集所有地址的需求(除堆棧外)。堆棧部分看起來很直觀。除了在彙編中明確列舉每個寄存器之外,是否有任何方法可以從寄存器中收集地址?假設x86_64位於類似POSIX的系統上,例如linux或mac。Boehm Weiser垃圾收集器的機制
的setjmp
由於Boehm和韋瑟實際上implemented their GC,則信息的基本來源是實現(它是開源)的源代碼。
要收集寄存器值,您可能需要破壞setjmp()
函數,該函數會將寄存器的副本保存在自定義結構中(至少應該在函數調用中保留的那些寄存器)。但是這種結構不是標準化的(其內容名義上是不透明的),並且setjmp()
可能由C編譯器特別處理,使其用於除longjmp()
之外的任何其他東西(這已經非常困難)。一行內聯組裝似乎更容易和更安全。
GC實現中的第一個硬件部分似乎能夠可靠地檢測堆棧的開始和結束(注意複數:可能有線程,每個都有自己的堆棧)。這需要深入研究OS ABI的記錄不當的細節。當我的桌面系統是運行FreeBSD的Alpha機器時,Boehm-Weiser實現無法運行(儘管它在同一處理器上支持Linux)。
第二個艱難的部分將是試圖進入世代,通過播放頁面訪問權限來阻止寫入訪問。這又需要閱讀一些可疑存在的文檔,以及一些內聯彙編。
我想在x86_86上他們使用flushrs彙編指令將寄存器放在堆棧上。如果這是錯誤的,我相信堆棧溢出的人會糾正我。
實現一個樸素的收集器並不難:它畢竟只是一個算法。難點在於說明,但我會加上最糟糕的:跟蹤異常是令人討厭的,並且停止線程更糟糕:在某些平臺上根本無法完成。還有一個問題,即捕獲所有交給操作系統的指針並暫時丟失(在Windows窗口消息處理程序中發生的很多事情)。
我自己的多線程GC與Boehm收集器類似,並且幾乎沒有標準C++(使用jmpbuf或多或少可以工作)以及稍微不太惡劣的環境(沒有例外)。但它通過合作阻止了世界,這非常糟糕:如果你有一個繁忙的CPU,空閒的等待它。 Boehm使用信號或其他操作系統功能嘗試停止線程,但支持非常脆弱。
另外請注意,英特爾i64處理器每個線程有兩個堆棧..有點難以說明這種東西一般。
那麼,當然,一旦你可以找到堆棧幀,你已經承諾足夠的實現細節來了解寄存器。 – 2010-09-11 21:32:36
我不確定你是對的,漢斯。也許我們可以依靠C運行時環境的結構來解決這個問題。如果我們調用一個將寄存器刷新到堆棧(flushrs)的非內聯malloc包裝器,也許我們可以使用任何局部變量的地址(malloc的本地變量)並在內存中移動更高的地址,直到達到argv [0]的地址。 – SetJmp 2010-09-29 13:39:26