gpt4 book ai didi

c - 如何坚持 C 编译器将局部变量放在堆栈上,而不是寄存器中

转载 作者:太空狗 更新时间:2023-10-29 17:22:47 24 4
gpt4 key购买 nike

我正在尝试将一个历史函数式语言解释器(KRC for EMAS)移植到现代系统(C for Unix),它有一个垃圾收集器,希望能够扫描堆栈中的指针以了解哪些指针当堆中的对象在 GC 期间移动时,它必须重新定位。为此,必须在堆栈中找到指向堆的所有函数参数和局部变量。

曾经有一段时间,“register”关键字的意思是“如果你愿意,你可以把这个变量放在一个寄存器中”,否则它就在堆栈上,但现在所有(GCC、Clang、Tinyc/tcc)C编译器似乎无论如何都会将局部变量放入寄存器,无法禁用此行为,结果是 GC 丢失了一些属于正在进行的函数的值,无法保留它们并破坏堆。

有没有办法告诉这些编译器中的任何一个使用原始的 C 语义,即所有局部变量都在堆栈上,除非你说“注册”?

我有几个棘手的“解决方案”:

  • 在各处添加额外的代码以获取每个面向堆的局部变量的地址并将其传递给虚拟函数,作为强制它位于内存位置的一种方式;
  • 使所有静态函数成为全局函数,以避免函数内联和由此产生的内联函数参数优化;
  • 用 stub 将 GC() 函数括起来,将所有机器寄存器压入堆栈,调用真正的 GC() 函数,然后弹出它们;

这一切似乎都可以改善问题,但非常不可靠且不可靠。

是否有更好的方法来实现所需的结果,确保所有函数参数和局部变量都在堆栈上?

最佳答案

我假设您使用了一种“标记和清除”GC。在这种情况下,您只需要在标记阶段开始时保存寄存器。我的建议是检查您的 GC,找到“标记和清除”操作开始的位置,并放置一个代码,将所有寄存器放入此处的可访问内存中。 setjmp 是实现此目的的半可移植方法(除非您正在使用 sparc)。

关于c - 如何坚持 C 编译器将局部变量放在堆栈上,而不是寄存器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28925253/

24 4 0