While Rust is one of my favorite languages to work on, over the last few years JVM based languages (namely Java and Scala) are my daily work tools. In an effort to better understand the lower level implementation details of the JVM I’ve been researching how to build my own. And to have some extra fun, why not do it in Rust?
Being a part 0 of a N part series, this post won’t have any code, just a short discussion on what our goal is and resources for the future.
This is not necessarily a series for learning Rust, so some knowledge of the language is necessary. Some knowledge of C++ and JVM based languages is a plus, but not strictly necessary.
The JVM Components
Roughly speaking, there are three main components in the JVM architecture:
- A class loader, which parses .class files into JVMs internal data structures;
- A bytecode verifier, which validates the data in these data structures;
- An Execution Engine, which interprets the byte code and executes the instructions;
Other related components are:
A compiler, which translate some language into bytecode
A Garbage Collector, which manages the memory of the JVM;
A JIT compiler, which compiles “hot” portions of the byte code into native code;
A Native Interface, which is able to “talk” with linked native code;
What We WON’T Be Building
We won’t be writing the following:
A compiler: I’m targeting writing the virtual machine, so we will assume our compiled code comes from the Gods and we just execute it;
A JIT compiler: Though this might be a stretch goal, this will take a lot of research time;
The new fastest most awesomest JVM to ever be built: Smarter people than me have been writing JVMs for over 25 years, this is just a research project;
What We Will Be Building
Our goal is to have:
A Native Interface;
Some form of garbage collection;
The target for this toy implementation is the JVM 8 specification.
One of the main points of this implementation is for it to be used for learning, so it should be really well documented. Part of this documentation will be this series of posts, the other part will be code documentation focused on following the specification to the letter.
Our main source of truth will be the The Java® Virtual Machine Specification for the Java SE 8 Edition. This document describes all the data structures, bytecodes and functionalities necessary for a complaint JVM.
Another important source I’ll be using is the openJDK8 source code (OpenJDK Mercurial Repositories) which can be downloaded using Mercurial or as a zip. We are particularly interested in the hotspot portion of the repositories (jdk8u hotspot).
Finally, the The Rust Programming Language — The Rust Programming Language and std — Rust will be used as basis for the Rust language itself.
Besides all the standard Rust tools (Cargo, Rustup, Clippy, etc), I’ll be using CLion + Rust Plugin as an IDE. The point is to be able to use the same IDE for our code and the openJDK implementation. Also, having access to a debugger is directly in the IDE is nice.
There are a few JVMs implemented in Rust already with similar goals to this project. I’d like to call attention to one particular implementation (https://github.com/kittylyst/ocelotter) which was part of a talk at Devoxx this year (https://www.youtube.com/watch?v=7ECbwgkHdAE&t=384s).
I’ve also tried my hand at this before, going as far as implementing a full class loader. The implementation can be found here. I’ll be using mostly the same structure, so you can take a peek at where we are going.
Well, thats it. On the next entry I’ll either go through the project organization or take a peek at the organization of the openJDK project, since it will be one of our main sources of inspiration.
See you then!