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

我编写了一个非常简单的编译器,将我的源语言翻译为字节码,这些代码由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?

我会很高兴,如果有人可以给我链接教程实施引用计数或帮助我这个非常具体的问题,如果有人有这个问题之前(我的问题是,我不明白什么时候增加,决定引用或计数是存储)


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

回应您的编辑:您可以使用隐式变量解决方案,或者您可以使用Objective-C中的“autorelease”概念。 你有一个放置在自动释放池中的对象,它会在很短的时间内释放,对象的接收者可以保留它。


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

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

如果print()的参数是对构造函数(new Object())的调用,那么在调用该函数的作用域中没有对该对象的引用,因此该对象位于该函数的作用域中,并且计数器应递增并相应地递减以进入和离开print()函数的范围。 如果构造函数在调用范围内调用并分配给变量,则它位于调用范围内。

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

链接地址: http://www.djcxy.com/p/20889.html

上一篇: Compiler: How to implement Reference Counting (in a simple VM)

下一篇: String in Java is object, so it should be reference?