• 2007-04-10

    合并Runtime

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://dreamhead.blogbus.com/logs/5006019.html

    终于将New Runtime的代码合并到XRuby的trunk中了。

    从开始写New Runtime到现在快有半年了,时至今日,才把它的主体结构合并到trunk中。主要原因是New Runtime和原有的Runtime差异太大。虽然二者起到的作用是类似,但结构和接口上的巨大差异使得合并成了一件很困难的事情。

    如果我没有记错的话,这是第三次进行合并的尝试。yawl在我写好了New Runtime之后,就进行了第一次尝试,试图将编译器移植到New Runtime上,结果很长时间代码都不能运行。虽然这次尝试没能成功,但是从New Runtime得到的继承结构应用到了trunk中。第二次尝试是在0.1.0发布之前,我亲自操刀合并。思路同上次类似,我直接把New Runtime的主要结构合并进来,之后,修改编译器。当时的代码已经可以运行很大一部分的代码,但依然是问题多多,最终没能赶在0.1.0发布之前完成。不过,这次的尝试倒是让我对代码生成部分有了一个比较清晰的认识。

    在0.1.3发布之后,我开始了第三次尝试。谈到New Runtime,yawl给了我个建议,一点一点来,不要试图一下子就把所有内容加进来。从善如流,我没有沿袭前两次那种大刀阔斧的修改方式,而是采用了小规模重构的方法。首先是对执行性能影响较大的Method Cache。说起来很简单,就是加一个简单的缓存,但因为已经存在了大量的测试用例,所以,让所有测试都通过是一个考验。这次修改基本上只改动Runtime的内部实现,几乎不动编译器端,所以,相对来说,影响还比较小。当所有测试用例通过的时候,我长出了一口气,至少成功的迈出了第一步。这次修改同时还加入了ID替换String的实现,所有测试用例通过之后,为了能够更充分的利用ID带来的优势,我又修改了编译器,让它直接生成利用ID的代码,相对来说,这步要简单得多。

    接下来的是更为复杂的类结构,同样,我依然采用的是小规模重构的方式。在开始之前,我划分了一下需要做的几件事,大体说来,分为三个部分singleton类的支持(用于支持为对象定义方法和meta类)、include类的支持(用于支持包含模块),整体结构的支持。

    按照顺序,我开始加入singleton类的支持时,我发现如果想让singleton类很好的运作,必须有对整体结构的支持,这两个工作关联性很大。为了不让自己陷入长时间的一无所获,我放弃了正在进行的singleton类的支持,转向include类的支持。果然,include类的支持相对来说,影响要小一些,编译器部分几乎没有任何修改,所以,很快通过了测试,这样,New Runtime已经有一部分进入到trunk之中。

    再回到singleton类支持时,有一少部分代码因为include类的原因,已经进入到trunk之中。其实,单纯支持singleton其实很容易,而且也几乎不要修改编译器,但正如前面提到的,如果让singleton类能够运行起来,必须要有整体的结构与之配合,所以,在有测试未通过的情况下,我就把整个的类结构全部合并进来了。之所以会很复杂,因为除了类结构本身,还要有编译器部分与之配合。这样,在应对Runtime修改的同时,还要考虑编译器生成代码的正确性。好在二者的表现通常是截然不同,在执行时出现的各种各样错误一定属于Runtime,而编译器的错误是代码根本不能正确执行,加载时就会出校验错,所以,一般很容易知道是哪里出了问题。无论如何,长时间的测试不能通过是一件很痛苦的事情,稍感欣慰的是,总有一点点的进步。

    惊喜总是不期而至,当我还在等待下一个错误的时候,突然所有测试用例通过了,那是一种很奇妙的感觉。虽然现在的Runtime还有不少要调整的地方,但是主要的结构已经进来了。回顾前两次的合并,之所以没能成功,主要是因为目标太大,一次要完成所有任务,很难很好的把握其复杂度。失败中也有收获,如果没有前两次的尝试打下的基础,这次的合并可能会更加复杂。

    合并New Runtime可是我在0.2.0要实现的一个重要目标,实现之后,便可以继续前进了。现在New Runtime不复存在,只有XRuby Runtime。



    引用地址: