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

时间:2012-07-05 16:49:07

标签: garbage-collection implementation reference-counting

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

如果有人可以给我实施引用计数的教程链接,或者如果有人之前遇到过这个问题,我会很高兴帮助我解决这个问题(我的问题是我不明白何时加入,引用或引用计数存储)

2 个答案:

答案 0 :(得分:0)

我认为文字会发生一些事情。您可以将它们视为文字数字,它们是永久性的常量,或者您可以在print之前拥有一个隐式变量,其重新计数为1,并在之后发布。

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

答案 1 :(得分:0)

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

查看有关Strings in Java的帖子。因此,在类似Java的语言中,每次连接它们时都会复制字符串,因为它们是不可变的。另外"this is a string"实际上是对字符串类的构造函数的调用。

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

在阅读有关内容时,维基百科是一个良好的开端,但是Andrew Appel's compiler book会很方便(应该有第2版,并且本书的C和ML版本也可用)。 Lambda-the-Ultimate是许多编程语言研究人员讨论事物的地方,所以绝对是一个值得关注的地方。