如何在复制垃圾收集器中转发来自寄存器的指针?

How to forward pointers from register in a copying garbage collector?

在复制垃圾收集器中,当我将对象从 from-space 复制到 to-space 时,某些对象可能会被存储在寄存器中的指针引用。 当垃圾收集发生时,该寄存器需要更新以指向 to-space.

问题是,垃圾回收是在程序的特定点执行的(比方说当用户分配内存时),因此,这将调用一个函数来进行回收。 反过来,这将使用可能是我们实际需要转发的寄存器。 因此,这会产生多个问题:

那么对于指针存储在指针中的对象,如何进行指针转发呢? 我们可以假设垃圾收集器是用 C 语言而不是汇编语言编写的(这样可以很容易地不覆盖寄存器)。

So how can I do the pointer forwarding for an object whose pointer is stored in a pointer

您只能原子地并在完成后使指针对所有其他线程可见

这由不同的 GC 完成。通常,GC 为此目的使用 barriers,一些代码在 GC 为 运行 时执行(就像对象的拦截器)。

所以当一些线程试图分配memory/change一些对象时, GC是运行,它不会直接改变pointer/object - 但是通过一些可以做到这一点的代码。更新转发指针通常是单发CAS,重新映射这个转发指针,使其对所有线程可见。

我已经解释了这是如何完成的 here,它 java 特定于 Shenandoah GC,但理论仍然相同。

编程语言或虚拟机的高效垃圾收集,从一开始就为垃圾收集而设计,始终与代码生成协作。

显然,垃圾收集器必须知道堆栈数据的布局才能对其进行分析。为了提高效率,生成的代码不需要在任何时间点支持垃圾收集,而只需要在某些 安全点 处在需要垃圾收集被标记时可能会自行挂起,或者,例如在你的单线程情况下,将直接调用垃圾收集器。

此时,代码必须以垃圾收集器可以理解的形式提供其数据。一个简单的解决方案是在调用垃圾收集器之前使用垃圾收集器已知的格式将寄存器压入堆栈,然后再将它们弹出。所以该机制不需要处理其他语言的寄存器保存机制,用于实现垃圾收集器本身。