中文 | English
| | |

YVM是用C++写的一个Java虚拟机,现在支持Java大部分功能,以及一个基于标记清除算法的并发垃圾回收器. 不过还有很多bug等待修复。
感兴趣的朋友pull request/fork/star吧。

Github repo

https://github.com/racaljk/yvm

已支持语言特性

高级特性逐步支持中,可以开Issue提议或者直接PR

  • Java基本算术运算,流程控制语句,面向对象。
  • RTTI
  • 字符串拼接(+,+=符号重载)
  • 异常处理(可输出stacktrace)
  • 创建异步线程
  • Synchronized(支持对象锁)
  • 垃圾回收(标记清除算法)

构建和运行

  • 先决条件

    • Boost(>=1.65) 请在CMakeLists.txt中手动配置Boost库位置
    • CMake(>=3.5)
    • C++14
    • gcc/msvc/mingw均可
  • 老生常谈
$ cd yvm
$ cmake .
$ make -j4
$ make test
$ ./yvm --help
Usage:--help                List help documentations and usages.--runtime arg         Attach java runtime libraries where yvm would lookup classes at--run arg             Program which would be executed soon
You must specify the "runtime" flag to tell yvm where it could find jdk classes, and also program name is required.
$ ./yvm --runtime=C:\Users\Cthulhu\Desktop\yvm\bytecode ydk.test.QuickSort

运行效果

  • helloworld

  • 快速排序

  • and more see its github repository readme.md...

开发文档

1. 从字节码到对象

MethodArea负责管理字节码到JavaClass的完整生命周期。MethodArea的方法是自解释的:

class MethodArea {
public:// 方法区需要从运行时目录中搜索相关的*.class文件MethodArea(const vector<string>& libPaths);~MethodArea();// 查看一个类是否存在JavaClass* findJavaClass(const string& jcName);//加载jcName类bool loadJavaClass(const string& jcName);//移除jcName(该方法用于垃圾回收器)bool removeJavaClass(const string& jcName);//链接jcName类,初始化static字段void linkJavaClass(const string& jcName);//初始化jcName,初始化静态字段,调用static{}void initJavaClass(CodeExecution& exec, const string& jcName);public://辅助方法,如果不存在jcName则加载 JavaClass* loadClassIfAbsent(const string& jcName);//如果未链接jcName则链接void linkClassIfAbsent(const string& jcName);//如果未初始化jcName则初始化void initClassIfAbsent(CodeExecution& exec, const string& jcName);
}

假设磁盘存在一个Test.class文件,它会经历如下过程:

Test.class[磁盘中]-> loadJavaClass("Test.class")[内存中] -> linkJavaClass("Test.class")->initJavaClass("Test.class")

现在虚拟机就可以使用这个JavaClass创建对应的对象了:

// yrt 是全局运行时对象,ma表示方法区模块,jheap表示堆模块
JavaClass* testClass = yrt.ma->findJavaClass("Test.class");
JObject* testInstance = yrt.jheap->createObject(*testClass);

2.1 对象内部构造

虚拟机执行时栈上存放的都是JObject,它的结构如下:

struct JObject {std::size_t offset = 0; const JavaClass* jc{};
};

offset唯一代表一个对象,所有在堆上面的操作都需要这个offset。jc指向对象的Class表示。
堆中的对象是按照<offset,fields>方式进行存放的:

[1]  ->  [field_a, field_b, field_c]
[2]  ->  []
[3]  ->  [field_a,field_b]
[4]  ->  [field_a]
[..] ->  [...]

只要我们持有offset,就可以查找/添加/删除对应的field

数组几乎和上面类似,只是多了长度,少了Class指针

struct JArray {int length = 0;std::size_t offset = 0;
};
[1]  ->   <3, [field_a, field_b, field_c]>
[2]  ->   <0, []>
[3]  ->   <2, [field_a,field_b]>
[4]  ->   <1, [field_a]>
[..] ->   <..,[...]>

2.2 从对象创建到消亡

上面提到,对象持有一个offset和jc,其中jc表示的JavaClass是由MethodArea负责管理的,offset则是由JavaHeap负责管理。JavaHeap提供了大量API,这里选取的是最重要的:

class JavaHeap {
public://创建对象和数组JObject* createObject(const JavaClass& javaClass);JArray* createObjectArray(const JavaClass& jc, int length);//获取对象字段auto getFieldByName(const JavaClass* jc, const string& name,const string& descriptor, JObject* object);//设置对象字段void putFieldByName(const JavaClass* jc, const string& name,const string& descriptor, JObject* object,JType* value);//设置数组元素void putElement(const JArray& array, size_t index, JType* value);//获取数组元素auto getElement(const JArray& array, size_t index);//移除对象和数组void removeArray(size_t offset;void removeObject(size_t offset);
};

还是Test.class那个例子,假设对应的Test.java构造如下:

public class Test{public int k;private String hello;
}

在第一步我们已经获取到了Test类在虚拟机中的类表示以及对象表示,现在就可以对类的字段进行操作了:

const JavaClass* testClass = yrt.ma->findJavaClass("Test.class");
JObject* testInstance = yrt.jheap->createObject(*testClass);
//获取hello字段
JObject*  helloField = yrt.jheap->getFieldByName(testClass,"hello","Ljava/lang/String;",testInstance);
//设置k字段
yrt.jheap->putFieldByName(testClass,"k","I",testInstance);

Ⅰ. 关于JDK

部分JDK类是JVM运行攸关的,但由于JDK比较复杂不便于初期开发,所以这里用重写过的JDK代替,源码参见javaclass目录,可以使用compilejava.bat进行编译,编译后*.class文件位于bytecode.
目前重写过的JDK类有:

  • java.lang.String
  • java.lang.StringBuilder
  • java.lang.Throwable
  • java.lang.Math(::random())
  • java.lang.Runnable
  • java.lang.Thread

Wiki和源码中有很多详细的开发文档,如果想探索关于YVM的更多内容,请移步浏览.

License

所有代码基于MIT协议

转载于:https://www.cnblogs.com/ysherlock/p/8688454.html

[开源JVM] yvm - 自制Java虚拟机相关推荐

  1. JVM内幕:Java虚拟机详解

    这篇文章解释了Java 虚拟机(JVM)的内部架构.下图显示了遵守 Java SE 7 规范的典型的 JVM 核心内部组件. 上图显示的组件分两个章节解释.第一章讨论针对每个线程创建的组件,第二章节讨 ...

  2. JVM统介——Java虚拟机架构

    0. 前言 Java虚拟机(Java virtualmachine)实现了Java语言最重要的特征:即平台无关性. 平台无关性原理:编译后的 Java程序(.class文件)由 JVM执行.JVM屏蔽 ...

  3. JVM笔记:Java虚拟机的字节码指令详解

    1.字节码 Java能发展到现在,其"一次编译,多处运行"的功能功不可没,这里最主要的功劳就是JVM和字节码了,在不同平台和操作系统上根据JVM规范的定制JVM可以运行相同字节码( ...

  4. 【JVM】<Java虚拟机>JVM架构各种**虚拟机

    目录 一.Java代码执行流程: 二.JVM架构模型: 1.这两种架构之间的区别: 2.反编译指令: 在IDEA中查看字节码: 三.JVM的生命周期: 1.虚拟机的启动: 2.虚拟机的执行: 3.虚拟 ...

  5. 自制java虚拟机_《深入理解Android:Java虚拟机ART》 —1.2.3 准备模拟器和自制系统镜像...

    1.2.3 准备模拟器和自制系统镜像 阅读源码是学习虚拟机的主要方法.但在某些关键地方,有时候很难确定代码逻辑的走向,这时就需要在源码中加一些日志来辅助我们观察虚拟机的行为.在此,笔者推荐使用模拟器和 ...

  6. JVM II(Java虚拟机,Java Virtual Machine)

    文章目录 7.助记符 相关助记符 8.JVM的4种引用级别 (1)强引用 (2)软引用(SoftReference) 软引用被GC回收例子: (3)弱引用(WeakReference) (4)虚引用( ...

  7. jvm十五:java虚拟机内存图

  8. jvm 调优 java 虚拟机 马士兵 马士兵 马士兵 笔记

    文档连接:http://download.csdn.net/download/disalong/10259953 例子代码连接:http://download.csdn.net/download/di ...

  9. java 虚拟机JVM

    1.概述 1991 年Sun 公司的James Gosling 等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒.PDA 等的微处理器:1994 年将Oak 语言更名为Java: ...

最新文章

  1. 北大元培系AI公司,一年狂揽三轮融资,最新A轮斩获数千万美元
  2. [译] Couchbase 使用 cbbackup 备份
  3. Android UI -- 布局介绍(布局包括FrameLayout, LinearLayout, RelativeLayout, GridLayout)
  4. TabLayout+Viewpager+Fragment实现分页滚动
  5. 【struts2】struts2中的Action详解
  6. VS code常用插件推荐(总结整理篇)
  7. 【JAVA线程间通信技术】
  8. 20155207 实验五 网络编程与安全
  9. Mac使用Docker搭建python测试执行环境
  10. TensorFlow saved_model 模块
  11. SpringMVC,3种不同的URL路由配置方法 [转]
  12. 创客匠人打造在线课堂,助力内容变现
  13. 人人开源后台项目maven构建(yyds)
  14. Win8/Win10 Ctrl+Alt+方向键 屏幕显示翻转解决办法
  15. 基于6818粤嵌开发板的2048游戏项目
  16. 【计算机网络】:IP分片详解及例题
  17. 不知不觉,我竟炼成了一枚 Markdown 深度用户
  18. MixMatch、UDA、ReMixMatch、FixMatch
  19. [反汇编练习]160个CrackMe之001
  20. 相位 unwrap 与 wrap 算法详解(附代码)

热门文章

  1. cf 1059e 思维 贪心 树
  2. jmeter插件监控cpu小节点
  3. [Cogs14] [网络流24题#1] 飞行员分配方案 [网络流,最大流,二分图匹配]
  4. Spring环境的搭建与测试 (spring2.5.6)
  5. GridView生成序号
  6. Asp.Net中用javascript实现弹出窗口永远居中
  7. vba 不等于_EXCEL表格VBA中的运算符
  8. VIsual Studio编译OpenCV:无法打开python27_d.lib(python36_d.lib)的问题
  9. C++ setw和setfill
  10. 水稻已知os基因号,利用DAVIA进行GO功能富集分析