2013-03-19 41 views
0

複製(分代)垃圾回收提供了任何形式的自動內存管理的最佳性能,但需要指向重新定位的數據塊。在支持這種內存管理技術的語言中,這是通過禁止指針運算並確保所有指針位於可識別對象的開始處而啓用的。複製生成代碼的垃圾回收

如果你使用JIT編譯器在運行時生成的代碼,事情看起來有點棘手,因爲調用堆棧上的返回地址將指向,代碼塊未開始,但他們中的隨機位置,所以修正爲一個問題。

這通常如何解決?

+0

我會說代碼在被傳遞給JIT之前被驗證。 – leppie 2013-03-19 16:52:11

回答

1

很多時候,你不要搬遷代碼。這是因爲修復堆棧和其他地址確實很複雜(認爲跨代碼片段跳轉),並且因爲您實際上並不需要爲此類代碼進行垃圾回收(因爲它只能由您編寫的代碼操縱,所以您可以做手動內存管理)。您也不希望創建大量機器代碼(與應用程序對象相比),因此碎片等不是問題。

如果你堅持運動的機器代碼和固定的堆棧,有的方式,我認爲:類似馬克緊湊,構建了「破錶」(我不知道在哪裏這個名字來源於; 「重定位表」可能會更清晰),它告訴你應該調整指向移動對象的指針的數量。現在,走棧的返回地址(當然是高度平臺特定的),並修復它們,如果它們引用重定位的代碼。而不是尋找完全匹配,搜索最高地址低於您當前正在替換的返回地址。你可以檢查這個地址的確是指通過查看對象大小而移動的一些機器代碼(畢竟你有一個指向對象開始的指針)。出於各種原因,這種方法對於所有對象都是不可行的。

還有其他原因可以做類似的事情。一些JIT編譯器具有棧上替換,這意味着創建一些機器代碼的新版本(例如,更優化或更少優化),並用它替換所有舊版本的舊版本。這比修復返回地址要複雜得多。您必須確保新版本在邏輯上繼續保持原有版本的懸掛位置。我是而不是熟悉這是如何實現的,所以我不會詳細討論。