当用作调用堆栈时,无垃圾的意大利面条堆栈会形成DAG吗?


9

我正在研究用于编程语言的实现技术,并且最近遇到了意粉堆栈,该堆栈被认为非常适合连续传递样式模型(假定它们在例如 Scheme和SML / NJ中使用)。为了简单起见,我们仅考虑此问题的单线程进程。

但是,我对Wikipedia上图表有些困惑 (也可以在其他地方找到)。特别是,我不明白这种情况如何发生。我只能想象,变灰的分支是无法访问的,应该进行垃圾回收。另一方面,由于我对如何使用意大利面条堆栈实现CPS的含糊理解,我无法想象如何在该结构中实现循环。我必须得出一个结论,它实际上是一个有向无环图,而不是一个“父指针树”,其非垃圾源与线程一样多,宿(与)(潜在)“退出点”一样多。

但是我对这种实现的理解很模糊,所以我想我可能缺少了一些东西。我希望有人可以在“意大利面条调用堆栈”上给我启发,我的意思是指Scheme和/或SML / NJ中用于实现基于CPS的过程的数据结构。

  1. 给定以下意大利面条调用堆栈:

    [exit point] <-- ... <-- [frame A] <-- [frame B (active)]
                                    ^
                                     `---- [frame C]
    

    据我了解,来自B的任何流控制要么通过跳到父级(A变为活动状态,现在不可访问的B现在是垃圾)来取消堆栈,要么用子图代替活动帧,仅使用B持有的引用或引用来连接到新的框架。执行无法流向框架C,这必须表示框架C是垃圾。

  2. 与以前的情况不同,我认为可能会出现以下无垃圾情况:

    [exit point] <-- ... <-- [frame W] <-- [frame X] <-- [frame Z (active)]
                                    ^                     |
                                     `---- [frame Y] <---´
    

    例如,我可以想象Z帧属于某个决策函数,该决策函数要么继续到X帧,要么继续到Y帧(两者都会返回到W)。这意味着意大利面条调用栈不是“父指针 ”。

  3. 但是,我无法想象可以构造循环的任何情况。以以下情况为例:

    [exit point] <-- ... <-- [frame P] --> [frame Q (active)]
                                    ^             |
                                    |             v
                                     `---- [frame R]
    

    我知道递归绑定是一回事,但我高度怀疑这是否明智。如果Q返回R,则帧Q被“花费”。如果R要返回到P,而P不能简单地返回到Q,因为它需要首先重新初始化。这样,循环将导致状态不一致。 (当然,除非我误解了此数据结构的用途,否则您只会将其中的节点用作当前框架的模板。)

从这些观察中,我必须得出一个结论,即意大利面条调用堆栈(不带垃圾)实际上是DAG。它是否正确?还是我误解了此数据结构的目的?


更新:

  • 我浏览以下论文的副本

    EA Hauck和BA Dent。1968年。Burroughs的B6500 / B7500堆栈机制。在1968年4月30日至5月2日的会议记录中,春季联合计算机会议(AFIPS '68(春季))。美国纽约州纽约市,ACM,245-251。DOI = http://dx.doi.org/10.1145/1468075.1468111

    本文似乎定义了Suguaro堆栈系统。事实证明,这种Suguaro堆栈系统是一种传统的调用堆栈,它允许多个“作业”遍历部分共享堆栈的框架。它绝对与延续无关。

  • 以下论文(及其1996年的随附论文)显然解释了SML / NJ编译器中发生的情况:

    钟韶和安德鲁·W·阿佩尔。2000。有效且安全的空间封闭转换。ACM Trans。程序。郎 Syst。22,1(2000年1月),129-161。DOI = http://dx.doi.org/10.1145/345099.345125

    我想在对这个问题做任何其他事情之前,应该先阅读本文(在作者的网站上复制)。“安全链接闭包”概念与Suguaro堆栈系统非常相似,因为它总是非常浅,仅用于共享自由变量:

    我们新的闭包转换算法使用安全链接的闭包(图1中的第3列),该闭包仅包含函数中实际需要的变量,但通过将具有相同生存期的变量分组到可共享记录中来避免闭包复制。[...]与链接的闭包不同,安全链接的闭包的嵌套级别永远不会超过两层(一层用于闭包本身;另一层用于记录不同的生存时间),因此它们仍然享有非常快的可变访问时间。

    本文还明确提到它不使用“任何运行时堆栈”:

    相反,我们将所有激活记录都视为连续函数的闭包,并在堆中的寄存器中分配它们。

    我认为我误解和/或误读了Wikipedia文章,因为意大利面条堆栈没有用于流量控制。但是,在仔细阅读Appel和Shao的论文之后,我也许可以参考闭包的依赖关系图而不是“ spaghetti调用栈”(显然不是问题)重述该问题。


在为自己思考并质疑所读内容中的断言方面做得很好。我希望您能得到一个好的答案,但我怀疑如果没有,您会做的很好。:)(如果将来将来能够这样做,请不要忘记回答您自己的问题!)
通配符

Answers:


2

意大利面条堆是父指针树吗?

是的,意大利面条堆栈是父指针树。您可以将意大利面条堆栈视为具有与共享结构的单链接列表相同的结构。从整体上看,列表的集合形成一棵树。但是当单独查看时,每个列表形成一个堆栈。

系统中的每个进程都将具有以下列表之一,代表其控制堆栈。列表的开头是堆栈的顶部(即活动框架)。它的next指针引用父框架。

您在图中看到的是多个流程的结构。“活动”过程的堆栈突出显示。不属于活动堆栈的树的部分显示为灰色。这些代表其他进程的堆栈。

意大利面条堆形成DAG吗?

由于Spaghetti堆栈是父指针树,因此它们的确是DAG。但是只有DAG也是树,才可以是意大利面条堆栈。所以不,意大利面条堆栈不会形成不是树的DAG。

您的决策函数示例将控制堆栈的结构与存储堆栈中的数据结合起来。当然,如果我们开始考虑数据,则可以形成任何结构。但是作为一种数据结构,意大利面条堆栈中的每个节点都将只有一个父节点。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.