C++手撸JVM——零号机
经过两三个月的佛系开发,码了5,6k行C++后,jvm的开发得到了实质性的进展
虽然它不支持utf8字符,没有实现数组功能,没有完成垃圾回收机制,比正常jvm慢了2~3个数量级,甚至部分指令还存在错误
但是,但是
。
。
。
它起码能跑起来啊(大声)
能跑起来,执行static方法,就比只能搜索类文件不知高到哪里去了。按软件工程增量模型的说法,也算完成“核心产品”了
况且还附带了测试模式,可以在此基础上进行改进。
所以以此为零号机,在此基础上进行完善
一号机:支持数组,完善对象方法的调用,修正部分指令
二号机:完成本地方法调用
三号机:实现异常处理机制
四号机:完成System.out.print的输出,优化代码,尽量提高jvm执行速度
五号机:实现内存管理,垃圾回收,类的验证算法
六号机:实现多线程,JIT等
恩,大体上这样吧
******************************************************************
零号机功能展示
一、进入方法区(MethodAera)测试
方法区是jvm中存放类信息的地方。jvm运行的过程中用到的类都要先从方法区进行查找,找不到再通过搜索.class文件的方式加载类。
进入方法区测试后,jvm新建一个方法区,并通过方法区类加载器进行加载类。
出于快速查找的目的,我用了map来存放jvm类信息。以类的全称名作为键,类信息存放的指针作为值
此时方法区空空如也:
二、加载测试类recur1
本次测试的是jvm能否正确执行recur1的代码:
从以上代码可以看出,recur1是利用递归完成1+2+3+。。。+1000的计算,然后输出计算结果,且结果为500500
第一步首先是加载recur1类:
首先jvm会去方法区查找是否有一个叫recur1的类,很明显找不到。。。
于是jvm通过递归搜索预设的类路径(classpath)找到了recur1,解析并加载到方法区。
然后根据recur1的类信息将其父类和实现接口加载到方法区。
加载完成后,方法区赫然出现recur1及其父类java/lang/Object的信息:
虽然recur1用到了doRec1的方法,但还没执行,所以暂时没将doRec1加载进来。
查看一下recur1的引用信息(类,方法,字段引用):
虽然doRec1暂时没加载,但也没跑得了了
输入main recur1,运行recur1(就不执行mains recur1了,毕竟递归1000次。。。):
正确执行,并打印出正确答案500500。
美中不足的是执行时间太长,居然用了1000多毫秒!正常的jvm也就1~2毫秒的事情。(执行1千万次累加更夸张,居然用了快10秒!)
额,还是别这么膨胀了,毕竟能跑起来已经不错了。