现代计算机语言通常分两部分实现:一是目标机器虚拟指令集编译器;二是一个所谓的高级语言虚拟机(或者叫简单语言虚拟机)--用来运行编译出来的虚拟程序。这种方法并不需要任何机器依赖的代码,因此简化了编译器。仅仅实现目标语言的运算符所需要的功能,可以减少虚拟指令集,从而能进一步简化编译器。
语言虚拟机运行虚拟程序有两种方式。最简单的方法是解释执行:解释器通过分发虚拟指令来仿真虚拟指令的轮流执行。更复杂但是更快速的方法是采用动态或者叫刚好及时(Just in time--JIT)编译器把虚拟指令翻译成机器指令,并且分发生成的机器指令。混合这两种方法的系统解释一部分虚拟程序,剩下的其他虚拟程序通过编译成本地代码来执行。
通常,编译过的代码执行起来比解释执行的虚拟指令更快。通过精心挑选虚拟程序的一部分来做JIT编译,混合模式的系统能比最快的解释器执行起来快的多。
尽快当前许多流行语言依赖于虚拟机,却只有相当少的编译器采用了JIT技术。Java虚拟机和Self是例外。结果就是,包括JavaScript,Python等重要的计算机语言的用户并没有享受到混合执行带来的性能提高。
我们研究的目标就是使得使用JIT技术来扩展解释器变得更加容易。文末描述了一种语言虚拟机的新架构,它极大提高解释执行的效率,同时它也减少了把一个编译器变成混合模式系统的复杂性。我们的技术有两个功能。首先,我们提出的JIT会识别并且编译“热程序执行路径”,或者叫行径。行径是一个有着一个入口(entry)多个出口(exit)的区域(region),区域比函数更容易被当前系统编译。而且,热行径有助于预测虚拟指令跳转的目的地址。这意味着甚至在行径被编译之前,这种编译器也可以有一个简单的方式来提高解释执行编译器的分支跳转之性能。
第二,我们实现的虚拟指令体(Virtual Instruction Bodies) 是轻量级的、能被调用的,同时我们把它集成到JIT编译器和解释器里面。这给JIT开发者一个简单方法来编译虚拟指令:虚拟指令被翻译成机器代码,或者生成相应虚拟指令体(Body)的调用。
JIT开发者的任务因此得以简化。他们只需要采用一个全功能的JIT编译器来编译虚拟指令的子集就可以了。而且,可被调用的虚拟指令体(Body)在解释器性能方面有积极的影响,因为他们提供一种简单的解释技术, subroutine threading, that very efficiently executes straight-line, or non-branching, regions of a virtual program.
We prototype our ideas in Java because there exist many high-quality Java interpreters and JIT compilers with which to compare our results. We are able to determine that the performance of our prototype compares favourably with state-of-the art interpreters like JamVM and SableVM. An obvious next step would be to apply our techniques to enhance the performance of languages that currently do not offer a JIT.
The discussion in the next few sections refers to many technical terms and techniques that are described in detail in Chapter , which introduces the basic concepts and related work, and Chapter , which provides a tutorial-like description of several interpreter techniques.