有没有什么基于C++或者scala的比较轻量级的JVM实现?

最近想写个JVM,一方面练习一下C++,另一方面就当学习Scala的习题 自己下载了OpenJDK的src,看了下HotSpot VM的实现,感觉有些庞大,而且跨平台的成分比较多,那么有什么比较轻量级的(即便是跨平台的内容没那么多,比如用VS2015开发只支持Windows的也可以)C++的JVM例子可供参考的吗? GitHub上面很多实现都是1个star2个star,也没什么活跃的更新,感觉实在不是很靠谱啊……
关注者
220
被浏览
10048

5 个回答

题主先说说想写个什么程度的JVM然后咱再来说具体的。
取决于写这个JVM的程度,有难度各异的许多不同选择。不过开源的JVM里用C++写的并不太多,用C写的更多一些。

===================================

C++实现的、开源的JVM

OpenJDK HotSpot VM

OpenJDK里的HotSpot VM是绝大部分用C++实现的。其实把它的JIT编译器都忽略、把GC只限制在Serial GC(DefNew + MarkSweepCompact)、解释器选用CppInterpreter而不是TemplateInterpreter、prims目录里JVMTI相关的东西以及services目录都不看的话,HotSpot VM的实现涉及的细节就没那么多,也并没有那么难懂的。
先放俩传送门吧:
  • Hotspot的源码应该怎样阅读? <- 这里我写了HotSpot VM的源码结构。当时我是针对OpenJDK6的来写的,到7和8都还差不多。OpenJDK9开始HotSpot VM的源码结构有略微调整,不过整体上还是一样。
  • 《HotSpot实战》的笔记 <- 关于HotSpot VM里的CppInterpreter的来龙去脉,请参考我写的这篇短文。

IBM OpenJ9 VM

IBM已经宣布会于明年(2017年)开源其J9 JVM,名为OpenJ9。这个JVM的核心VM最初是用Smalltalk写的生成器,根据配置在每个平台上生成对应的C代码然后编译出核心VM来。现在应该是用C重写了一遍。核心VM(主要是解释器、类加载器等功能)尚未开源
J9的GC与JIT编译器则是用C++实现的,跟HotSpot VM一样都是相当优化的实现,所以实现得比较复杂,未必适合题主参考。这些部分的核心组件现在已经在Github上开源了,位于:GitHub - eclipse/omr: Cross platform components for building reliable, high performance language runtimes

Oracle/Sun CLDC-HI VM

在Java ME领域,Oracle/Sun的"CLDC HotSpot Implementation"(简称CLDC-HI,也叫做Monty VM)也是一个用C++实现的JVM。它比Java SE版的HotSpot VM简单得多,题主要是感兴趣的话可以参考一下。它的源码可以在phoneME Feature项目中找到:Phoneme — Project Kenai

Mysaifu JVM

Mysaifu JVM是一个可以跑在Windows Mobile上的Java ME JVM实现。这个实现相当简单,题主或许可以先从这个参考一下看看。
传送门:

Google AOSP Android Runtime(ART)

没错,Android Runtime(ART)也是一个主要用C++实现的JVM。只是很傲娇的使用与JVM的字节码指令集有非常强的对应关系的Dalvik字节码指令集而已。
ART可能是用C++实现的JVM里,C++的用法最现代的一个了。要参考现代C++在JVM实现中的用法的话,可以看看ART。
传送门:

ReadyTalk Avian

Avian是一个用C++实现的JVM子集。这个子集的功能也颇可用了。而且它支持把Java程序AOT编译成bootimage,挺有趣的。
传送门:

===================================

Scala实现的、开源的JVM

呃,Scala实现的JVM么。Scala自身一般就是在JVM上运行的,用Scala来实现JVM就进入了“metacircular VM”(元循环VM)——用自己实现自己的VM——的领域。

这样的VM可以有相当多不同的取舍,实现难度可以差非常非常多。
取舍点有例如:
  • 对象模型要不要自己实现?
  • GC要不要自己实现?
  • 线程模型要不要自己实现?
  • 是做解释器还是编译器,还是两者都要?
  • 与native库要如何交互?
举个简单的例子,如果对上面的问题回答是“只做一个解释器,其它全部交给底下的JVM去跑”的话,那这做起来就超级简单。依靠Scala的模式匹配写个简单的字节码解释器简直容易。然而这样的实现无法自举,玩玩很快就腻了。

而如果回答是“全部都要自己实现,并且要通过自己实现的编译器来自举(bootstrap)”的话,这实现就复杂很多了。能自举的JVM就好玩很多,可以天天玩月月玩年年玩 >_<

在上述两个极端之间当然还有很多中间选项。但如果以“自举”为界线的话,要自举的话写个字节码到机器码的编译器是必要条件。

简单的、不能自举的用Scala实现的JVM,有一个很出名的、新加坡的Haoyi Li大大写的:GitHub - lihaoyi/Metascala: A JVM written in Scala,“3000行Scala写成的JVM”。

能自举的用Scala写的JVM我还没听说过。如果谁听说过这样的项目的话请在评论区告知,我马上更新答案~
用纯Java实现的metacircular VM倒是有好几个。例如说,比较现代的有源自Oracle/Sun的Maxine VM与源自IBM的Jikes RVM。与Jikes RVM颇有渊源的JoeQ也算一个。用Java能做的,用Scala当然也可以做,只是我没见过实际用Scala实现的metacircular JVM而已。

不过!有用Scala实现的比JVM更底层一点的研究性框架,叫做MicroVM:The Mu Micro Virtual Machine Project。MicroVM(或者叫uvm)的研究目的是为所有managed runtime提供一个基础的实现框架,当然在它的基础上要实现JVM也是可能的。
MicroVM有过几个Scala的实现,不过我不太记得它们能不能bootstrap了…据说是可以bootstrap。

另外提个对题主来说没啥参考价值的:Java的AOT编译器产品中很出名的Excelsior JET,它当前版本的Java字节码到机器码的编译器就是用Scala实现的。不过这玩儿不开源,所以对题主帮助不大。举这个例子主要是想说明用Scala写JVM的思路是真实可行,有应用在实际产品中的。
github.com/lihaoyi/Meta

顺便八卦下,Haoyi Li是李显龙的小儿子…MIT CS三年就毕业了…