编译器:如何实现引用计数(在简单 VM 中)



我写了一个非常简单的编译器,将我的源语言翻译成字节码,这段代码由虚拟机处理(作为一个简单的堆栈机器,所以 3 + 3 将被翻译成

push 3
push 3
add

现在我在垃圾收集中挣扎(我想使用引用计数)。我知道它的基本概念,如果分配了一个引用,该对象的引用计数器就会递增,如果它离开范围,它就会递减,但我不清楚的是 GC 如何释放传递给函数的对象......

这里有一些更具体的例子来说明我的意思

string a = "im a string" //ok, assignment, refcount + 1 at declare time and - 1 when it leaves scope    
print(new Object()) //how is a parameter solved? is the reference incremented before calling the function?
string b = "a" + "b" + "c" //dont know how to solve this, because 2 strings get pushed, then concanated, then the last gets pushed and concanated again, but should the push operation increase the ref count too or what, and where to decrease them then?
如果

有人能给我实现引用计数的教程链接,或者如果有人以前遇到过这个问题,我会很高兴帮助我解决这个非常具体的问题(我的问题是我不明白何时 inc、dec 引用或计数存储在哪里)

我认为文字可能会发生一些事情。你可以把它们当作文字数字,它们是常量并且永远存在,或者你可以有一个隐式变量,它在print之前重新训练计数为 1,并在之后释放它。

为了响应您的编辑:你可以使用隐式变量解决方案,也可以使用Objective-C中的"自动发布"概念。您有一个放置在自动释放池中的对象,该对象将在短时间内释放,在该池中,对象的接收方可以保留它。

首先,您的语言允许将哪些类型的对象放在堆上?字符串?你有可变或不可变的字符串吗?

看看这篇关于 Java 中的字符串的文章。因此,在Java中,每次连接它们时都会复制语言字符串,因为它们是不可变的。此外,"this is a string"实际上是对字符串类构造函数的调用。

如果要print()的参数是对构造函数(new Object())的调用,则在调用函数的作用域中没有对对象的引用,因此对象位于函数的作用域中,计数器应根据进入和离开print()函数的作用域而递增和递减。如果在调用作用域中调用构造函数并将其分配给变量,则该构造函数位于调用作用域中。

在阅读这些东西时,维基百科是一个好的开始,但安德鲁·阿佩尔的编译器书会很方便(那里应该有第二版,并且也有这本书的 C 和 ML 版本)。Lambda-the-Ultimate是许多编程语言研究人员讨论事情的地方,所以绝对是一个值得关注的地方。

最新更新