Skip to content

garbage collection and vm

· xieyuheng

root scanning 问题 ​

读了很多论文之后:

  • 2001-constant-time-root-scanning-for-deterministic-garbage-collection.md
  • 1984-reference-count-garbage-collection.md
  • 2002-accurate-garbage-collection-in-an-uncooperative-environment.md
  • 2009-accurate-garbage-collection-in-uncooperative-environments-revisited.md

我发现 GC 的 root scanning 问题, 对于带有 GC 但是没有静态类型系统的语言而言, root scanning 问题太难了。

目前所发现的解决方案都有严重的限制,比如:

  • 或者要求所有的 object pointer 不能保存到寄存器中。

  • 或者要求每次把一个可能是 object pointer 的 value 保存到寄存器中时, 都要把这个值备份到 shadow stack 中。

  • 或者在 safepoint 的 slow path 中, 需要扫描整个 call stack, 或 copy 并且 unwind 整个 call stack。

编译到 native code,而不是使用 vm, 是放弃了 vm 所带来的好的特性,来换取速度。 但是上面这些方案都会导致,换不来太多的速度。

可能的结论是:

  • 如果想要为纯粹的动态类型语言实现 GC, 还是用 vm 来实现比较好,而不是编译到 native code。

目前我的方案所引入的限制是:

  • 禁止 primitive function 调用 x-lisp function。

尽管有上面的结论,我还是想尝试在这个限制下实现 native code + GC。

另外,我还可以继续调研 GC 方案。 看看还有没有别的思路。

reference counting 作为备选方案 ​

1984-reference-count-garbage-collection.md 是一个不错的备选。

这是一个纯粹在运行时来解决 root scanning 问题的方案。

但是这对于实现 native 编译器而言也不太对。 因为每个 assignment 都潜在地需要 reference counting:

  • const instruction: 可以根据 value 的类型决定是否需要 reference counting。

  • call 和 apply instruction: 每次返回值,都要在运行时检查是否需要 reference counting。

    • primitive function 的 call, 有时可以确定返回值是否是 object。