私はプログラミング言語の実装手法を調べています。最近、スパゲッティスタックに出会いました。これは、継続スキームスタイルモデル(SchemeやSML / NJなどでの使用を想定)に適していると思われ ます。簡単にするために、この質問ではシングルスレッドプロセスのみを検討します。
ただし、Wikipediaの図 (他の場所にもあります)には少し混乱してい ます。特に、そのような状況がどのように起こり得るのか、私にはわかりません。灰色で表示されたブランチは到達不可能であり、ガベージコレクションの対象となることしか想像できません。一方、スパゲッティスタックを使用してCPSを実装する方法については漠然と理解しているため、その構造でループが発生する方法を想像することはできません。「親ポインタツリー」ではなく、実際には有向非循環グラフであり、スレッドと同じ数の非ガベージソースと、(潜在的な)「出口ポイント」と同じ数のシンクがあると結論付けなければなりません。
しかし、この実装についての私の理解はかなり曖昧なので、おそらく何かを見落としていると思います。ここで「スパゲッティコールスタック」について誰かに教えていただければ幸いです。つまり、CPSベースのプロセスを実装するためにSchemeやSML / NJで使用されるデータ構造を意味します。
次のスパゲッティコールスタックがあるとします。
[exit point] <-- ... <-- [frame A] <-- [frame B (active)] ^ `---- [frame C]
私が理解している限り、Bからのフロー制御は、親にジャンプしてスタックを巻き戻します(Aがアクティブになり、到達不能Bはガベージになります)、またはBまたは参照が保持する参照のみを使用して接続されたサブフレームでアクティブフレームを置き換える新しいフレームに。実行はフレームCにフローできません。これは、フレームCがゴミであることを意味します。
以前の状況ではなく、次のガベージフリーの状況が発生する可能性があると思います。
[exit point] <-- ... <-- [frame W] <-- [frame X] <-- [frame Z (active)] ^ | `---- [frame Y] <---´
たとえば、フレームZが、フレームXまたはフレームY(どちらもWに戻る)で継続する決定関数に属していると想像できます。これは、スパゲッティコールスタックが「親ポインターツリー」ではないことを意味します。
ただし、ループを構成できる状況は想像できません。たとえば、次の状況を考えます。
[exit point] <-- ... <-- [frame P] --> [frame Q (active)] ^ | | v `---- [frame R]
再帰的なバインディングが重要であることは知っていますが、これが賢明であるかどうかは非常に疑問です。QがRに戻る場合、フレームQは「使用済み」です。RがPに戻る場合、Pは最初に再初期化する必要があるため、単にQに戻ることはできません。そのため、ループは矛盾した状態を引き起こします。 (もちろん、私がこのデータ構造の目的を誤解している場合を除き、あなたはその中のノードを現在のフレームのテンプレートとしてのみ使用します。)
これらの観察から、スパゲッティコールスタック(ガベージなし)は実際にはDAGであると結論付ける必要があります。これは正しいです?それとも、このデータ構造の目的を誤解していますか?
アップデート:
私は次の紙のコピーをざっと読みました:
EA HauckとBA Dent。1968。バローズのB6500 / B7500スタックメカニズム。で4月30日の議事録- 1968年5月2日、春の共同コンピュータ会議(AFIPS '68(春))。ACM、ニューヨーク、ニューヨーク、米国、245-251。DOI = http://dx.doi.org/10.1145/1468075.1468111
この論文は、Suguaro Stack Systemを定義しているようです。結局のところ、このSuguaroスタックシステムは、複数の「ジョブ」が部分的に共有されたスタックのフレームをウォークスルーできるようにする従来のコールスタックです。継続には絶対に関係ありません。
次の論文(およびその1996年の関連論文)は、SML / NJコンパイラで何が行われているのかを明らかに説明しています。
チョン・シャオとアンドリュー・W・アペル。2000.効率的で安全なスペースクロージャ変換。ACM Trans。プログラム。ラング。システム。22、1(2000年1月)、129-161。DOI = http://dx.doi.org/10.1145/345099.345125
この質問について他に何かする前に、この論文(著者のウェブサイトにコピー)を読むべきだと思います。「安全にリンクされたクロージャ」の概念は、常に非常に浅く、自由変数を共有することのみを目的としているという点で、Suguaroスタックシステムと非常に似ています。
新しいクロージャー変換アルゴリズムは、実際に関数で必要な変数のみを含む安全にリンクされたクロージャー(図1の3列目)を使用しますが、同じ存続期間を持つ変数を共有可能なレコードにグループ化することでクロージャーのコピーを回避します。[...]リンクされたクロージャーとは異なり、安全にリンクされたクロージャーのネストレベルは2つを超えない(1つはクロージャー自体のレイヤー、もう1つは寿命の異なるレコードのレイヤー)ため、変数アクセス時間は非常に高速です。
また、「ランタイムスタック」を使用しないことも明示的に述べています。
代わりに、すべてのアクティブ化レコードを継続関数のクロージャとして扱い、ヒープ内のレジスタに割り当てます。
スパゲッティスタックはフロー制御に使用されていないため、Wikipediaの記事を誤解したり、誤解したりしていると思います。ただし、AppelとShaoの論文を注意深く読んだ後、「スパゲッティコールスタック」ではなく、クロージャーの依存関係グラフを参照して質問をもう一度述べることができます(これは明らかにそうではありません)。