编译为C时的垃圾收集

编译为C时的垃圾收集,c,compiler-construction,garbage-collection,C,Compiler Construction,Garbage Collection,将垃圾收集语言编译为C时,垃圾收集的技术有哪些?我知道两个: 维护在数据结构中显式保存所有根的卷影堆栈 使用像Boehm这样的保守垃圾收集器 第一种技术很慢,因为您必须维护阴影堆栈。可能每次调用函数时,都需要将局部变量保存在数据结构中 第二种技术也很慢,而且由于使用了保守的垃圾收集器,因此无法回收所有垃圾 我的问题是:在编译到C时,垃圾收集的最新技术是什么?请注意,我指的不是在用C编程时进行垃圾收集的方便方法(这是Boehm垃圾收集器的目标),而是在编译到C时进行垃圾收集的方法 可能每次调用函数

将垃圾收集语言编译为C时,垃圾收集的技术有哪些?我知道两个:

  • 维护在数据结构中显式保存所有根的卷影堆栈

  • 使用像Boehm这样的保守垃圾收集器

  • 第一种技术很慢,因为您必须维护阴影堆栈。可能每次调用函数时,都需要将局部变量保存在数据结构中

    第二种技术也很慢,而且由于使用了保守的垃圾收集器,因此无法回收所有垃圾

    我的问题是:在编译到C时,垃圾收集的最新技术是什么?请注意,我指的不是在用C编程时进行垃圾收集的方便方法(这是Boehm垃圾收集器的目标),而是在编译到C时进行垃圾收集的方法

    可能每次调用函数时,都需要将局部变量保存在数据结构中

    不,您不需要-您可以将局部变量保留在C堆栈上,并且仍然对它们进行迭代:将所有引用变量放在一个数组中,并将指向该数组的指针添加到一个链表中,在输入新的堆栈帧时,将一个节点附加到该链表中

    模型:

    struct vm
    {
        struct scope *root;
    };
    
    struct scope
    {
        struct scope *prev, *next;
        size_t size;
        struct ref *refs;
    };
    
    void foo(struct vm *vm, struct scope *caller)
    {
        struct ref local_refs[42];
        struct scope scope = {
            caller, NULL, sizeof local_refs / sizeof *local_refs, local_refs };
    
        caller->next = &scope;
    
        // ...
    
        caller->next = NULL;
    }
    

    然而,如果你想支持连续/非局部跳转,你必须跳过一些主要的障碍。在这种情况下,堆分配所有东西更容易。

    这是一个令人讨厌的问题。这也是为什么LLVM和C很流行的原因(它们允许垃圾收集而无需恶意处理)。原始语言中的类型系统是基于DAG还是基于通用图?DAG只需要引用计数(由于是非循环的)。不幸的是,一般的图。我也考虑过引用计数,但这似乎并不能解决所有问题,因为您仍然需要一种方法来遍历根以收集循环…编译为C意味着什么?您能给出一个示例命令吗?当您使用C作为其他语言的编译器的目标语言时,这种技术是最有用的,因为它容易出错,并且需要仔细跟踪每件事情,这是一种有趣的技术。然而,这难道不意味着局部变量不存在于寄存器中,这很可能比调用时保存局部变量还要慢吗?@Jules:编译器仍然可以在寄存器中自由缓存任何局部值以进行计算,但你是对的,它必须在函数调用时同步这些值;我必须考虑一下,通过告诉编译器调用的函数不会修改局部变量,适当使用
    const
    restrict
    可以如何改善这种情况。。。