jvm.go -- 设计和实现

SpiderDog · · 4156 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

jvm.go

jvm.go是一个完全用Go语言实现的JVM,关于这个项目的发起原因和简单介绍可以看这篇文章

最新进展和下一步计划

jvm.go的开发已经进行了一个半月了,除了HelloWorld和一些简单的Java代码以外,JUnit也可以正常运行了。下一步的计划是在jvm.go上把Jetty跑起来。下面介绍一下jvm.go的一些关键部分的设计和实现。

目录结构

  • jvmgo jvm的go语言实现
    • cmdline 这个包用来解析java命令行参数
    • classfile 这个包把[]byte转化成ClassFile结构
    • classpath 这个包实现了class文件查找
    • native rt.jar里的本地方法实现
    • jvm jvm核心功能
      • instructions 指令集
      • rtda 运行时数据区(Runtime Data Area),线程、堆栈、栈帧等都在这个包里
        • class 类和对象(以及数组)等在这个包里
  • testclasses 用来测试jvm的Java代码,Gradle项目

核心JVM

实现核心JVM其实是相对比较简单的,对照着JVM规范,把Thread、Frame、Operand Stack、Local Vars、Class、Object、Array、指令集等一一实现就可以了。下面以FrameStack和OperandStack为例,简单介绍一下:

type Stack struct {
	maxSize uint
	size    uint
	_top    *Frame // stack is implemented as linked list
}
type OperandStack struct {
	size  uint
	slots []Any
}
FrameStack是用链表(LinkedList)实现的,OperandStack内部其实用了Slice。

指令集

为了更好的代码可读性,每一个指令都实现成一了个struct,下面是iinc指令的完整代码:

package instructions

import "jvmgo/jvm/rtda"

// Increment local variable by constant
type iinc struct {
	index  uint
	_const int32
}

func (self *iinc) fetchOperands(decoder *InstructionDecoder) {
	self.index = uint(decoder.readUint8())
	self._const = int32(decoder.readInt8())
}

func (self *iinc) Execute(frame *rtda.Frame) {
	localVars := frame.LocalVars()
	val := localVars.GetInt(self.index)
	val += self._const
	localVars.SetInt(self.index, val)
}
因为大部分指令都是需要操作OperandStack和/或LocalVars的,所以指令的Execute方法参数设计接收为*Frame类型的参数:
type Instruction interface {
	fetchOperands(decoder *InstructionDecoder)
	Execute(frame *rtda.Frame)
}

类库和本地方法

最初开始写jvm.go的时候,用的是OpenJDK的rt.jar。但是因为要经常查看rt.jar的Java代码,用IDE可以直接跳进Oracle JDK的rt.jar代码里。所以为了方便,后来就改为针对Oracle的rt.jar进行开发。rt.jar里有几千个本地方法,目前为止,只实现了不到100个。下面是本地方法的类型定义:

type NativeMethod func(frame *rtda.Frame)

垃圾回收

Go本身就是垃圾回收语言,所以jvm.go没有单独实现垃圾回收机制。

线程

jvm.go把每个Java线程都映射为一个goroutine,下面是Thread.start0()本地方法的实现代码:

// private native void start0();
// ()V
func start0(frame *rtda.Frame) {
	vars := frame.LocalVars()
	this := vars.GetThis()

	newThread := rtda.NewThread(this)
	runMethod := this.Class().GetInstanceMethod("run", "()V")
	newFrame := newThread.NewFrame(runMethod)
	newFrame.LocalVars().SetRef(0, this)
	newThread.PushFrame(newFrame)

	this.LockState()
	this.SetExtra(newThread)
	this.UnlockState()

	go interpreter.Loop(newThread)
}

总结

jvm.go已经有了很大的进展,但是离完整的JVM实现还差的很远。希望对Java和JVM,或者Go语言感兴趣的朋友可以review代码,甚至贡献代码。希望jvm.go有朝一日能够成为一个正真的jvm,一个有用的jvm微笑


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:SpiderDog

查看原文:jvm.go -- 设计和实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4156 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传