This is a creation in Article, where the information may have evolved or changed.
Jvm.go
Jvm.go is a fully implemented JVM with the go language, and the reason for this project and a brief introduction can be viewed in this article.
Latest developments and Next steps
Jvm.go has been in development for 1.5 months, and JUnit works well in addition to HelloWorld and some simple Java code. The next plan is to run the jetty on the Jvm.go. Here's a look at some of the key parts of Jvm.go's design and implementation.
Directory structure
- Jvmgo JVM's Go language implementation
- CmdLine This package is used to parse Java command-line arguments
- Classfile this bag to convert []byte into Classfile structure
- Classpath This package implements a class file lookup
- Local method implementation in native Rt.jar
- JVM JVM Core Functionality
- Instructions instruction Set
- RTDA runtime data area, thread, stack, stack frame, etc. in this package
- Class classes and objects (and arrays) are in this package.
- Testclasses Java code used to test the JVM, Gradle project
Core JVM
The implementation of the core JVM is relatively simple, compared to the JVM specification, the thread, Frame, Operand Stack, Local Vars, Class, Object, Array, instruction set, such as one by one implementation can be. The following is an example of Framestack and Operandstack, a brief introduction:
Type stack struct {maxSize uintsize uint_top *frame//stack is implemented as linked list}
Type operandstack struct {size uintslots []any}
Framestack is implemented with a linked list (LinkedList), the Operandstack internal actually uses the slice.
Instruction Set
For better code readability, each instruction is implemented as a struct, and the following is the complete code for the IINC directive:
Package Instructionsimport ' JVMGO/JVM/RTDA '//Increment local variable by constanttype 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._constlocalvars.setint (Self.index, Val)}
Since most instructions are required to manipulate operandstack and/or Localvars, the Execute method parameter of the instruction is designed to receive parameters of type *frame:
Type instruction Interface {fetchoperands (decoder *instructiondecoder) Execute (frame *RTDA. Frame)}
class libraries and Local methods
When I first started writing jvm.go, I used the Rt.jar of OPENJDK. But because you want to see Rt.jar Java code often, you can jump directly into the Oracle JDK's Rt.jar code with the IDE. So for convenience, it was later developed for Oracle's Rt.jar. There are thousands of local methods in Rt.jar, so far, only less than 100 have been implemented. The following is the type definition for the local method:
Type Nativemethod func (frame *RTDA. Frame)
Garbage collection
Go itself is a garbage collection language, so jvm.go does not implement garbage collection alone.
Thread
Jvm.go map each Java thread to a goroutine, the following is the implementation code for the Thread.start0 () Local method:
Private native void Start0 ();//() Vfunc 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)}
Summarize
Jvm.go has made a lot of progress, but it's far from complete JVM implementations. Friends who want to be interested in Java and the JVM, or the Go language, can review code or even contribute code. Hopefully the jvm.go will someday be a real JVM, a useful JVM.