C++手撸JVM——零号机

经过两三个月的佛系开发,码了5,6k行C++后,jvm的开发得到了实质性的进展

虽然它不支持utf8字符,没有实现数组功能,没有完成垃圾回收机制比正常jvm慢了2~3个数量级,甚至部分指令还存在错误

但是,但是

它起码能跑起来啊(大声)

 

能跑起来,执行static方法,就比只能搜索类文件不知高到哪里去了。按软件工程增量模型的说法,也算完成“核心产品”了

况且还附带了测试模式,可以在此基础上进行改进。

所以以此为零号机,在此基础上进行完善

 

一号机:支持数组,完善对象方法的调用,修正部分指令

二号机:完成本地方法调用

三号机:实现异常处理机制

四号机:完成System.out.print的输出,优化代码,尽量提高jvm执行速度

五号机:实现内存管理,垃圾回收,类的验证算法

六号机:实现多线程,JIT等

恩,大体上这样吧

******************************************************************

零号机功能展示

 

一、进入方法区(MethodAera)测试

C++手撸JVM——零号机

 

方法区是jvm中存放类信息的地方。jvm运行的过程中用到的类都要先从方法区进行查找,找不到再通过搜索.class文件的方式加载类。

进入方法区测试后,jvm新建一个方法区,并通过方法区类加载器进行加载类。

出于快速查找的目的,我用了map来存放jvm类信息。以类的全称名作为键,类信息存放的指针作为值

C++手撸JVM——零号机

此时方法区空空如也:

C++手撸JVM——零号机

 

二、加载测试类recur1

本次测试的是jvm能否正确执行recur1的代码:

C++手撸JVM——零号机

从以上代码可以看出,recur1是利用递归完成1+2+3+。。。+1000的计算,然后输出计算结果,且结果为500500

 

第一步首先是加载recur1类:

C++手撸JVM——零号机

首先jvm会去方法区查找是否有一个叫recur1的类,很明显找不到。。。

于是jvm通过递归搜索预设的类路径(classpath)找到了recur1,解析并加载到方法区。

然后根据recur1的类信息将其父类和实现接口加载到方法区。

 

加载完成后,方法区赫然出现recur1及其父类java/lang/Object的信息:

C++手撸JVM——零号机

虽然recur1用到了doRec1的方法,但还没执行,所以暂时没将doRec1加载进来。

 

查看一下recur1的引用信息(类,方法,字段引用):

C++手撸JVM——零号机

虽然doRec1暂时没加载,但也没跑得了了

 

输入main recur1,运行recur1(就不执行mains recur1了,毕竟递归1000次。。。):

C++手撸JVM——零号机

正确执行,并打印出正确答案500500。

美中不足的是执行时间太长,居然用了1000多毫秒!正常的jvm也就1~2毫秒的事情。(执行1千万次累加更夸张,居然用了快10秒!)

额,还是别这么膨胀了,毕竟能跑起来已经不错了。