関数言語をポータブルC言語にコンパイルし、さまざまな理由から、控えめなガベージコレクションではなく正確なものを望むと仮定します。ガベージコレクタがCスタック上のポインタの有無を把握するための移植可能な方法はありません(一般的にはまったくありません)。私にはこの問題の2つの解決策があるようです:関数言語をC言語にコンパイルする
シャドースタック。各C関数がポインタの有無に関する情報を簿記情報として保持するようにします。これは、例えば、 LLVM。
機能的な言語をコンパイルしていることを利用してください。つまり、メインラインコードには副作用がありません。アロケータがメモリ不足を検出すると、ガベージコレクタ自体を呼び出すのではなく、longjmpを持つ現在の操作をメインループにアボートします。メインループはガベージコレクタを呼び出します(ポインタを含む可能性のある変数のセットがわかっているコンテキストその後、操作を再開します。
あなたが第二のアプローチが適用され、純粋な関数型言語を扱っている場合、手書きのC.と混合する複数の第一の方法より効率的なだけでなく、より簡単でなければならない、と私には思わ
私は見落としている問題はありますか?このテクニックの既存の議論や実装への言及はありますか?
おそらく役に立ちませんが、私は自分のスキームインタープリタのためにマークスイープを書くのを最初に試みました。パフォーマンスが吸い上げられたので、クロスランタイムスタックイントロスペクションが実質的に不可能なため、Cランタイムのスタックの外側に純粋に仮想スタックがありました。パフォーマンスも吸引されましたが、gdb/dddなしでデバッグするのは簡単でした。私は、これが通訳者であり、実装のコンパイラ段階に達したときにそれに取り組むことにしました(これは決して一般的に終了しませんでした)。 – Deleted
現在の操作をどのように再開する予定ですか?チェックポイントを時折保存してから、最後の良いものを復元してください(どのように?) –
@ n.m .:その点で重要なのは、 "コードには副作用がありません"です。質問者は純粋な関数型言語を前提としているので、状態は変更されません。チェックポイントを「取る」必要はありません。以前の状態にジャンプするときに、言語が変更を行うことができないため、変更を元に戻す必要はありません。原則として、コード内のあなたの位置は、プログラムの状態について知る必要があるすべてのことを示します。 –