Jago
A simplified Java virtual machine written in Go language. This project is to learn JVM specification in depth and try to understand the behind-the-scene behaviour when a Java program runs.
I only refer to "Java Virtual Machine Specification" and then figure out how we should design one. I ignore some production-level features and make it as simplified as possible so as to demonstrate the idea. For the educational purpose, it is enough.
If you have no time to read OpenJDK source code or always guess the JVM behaviour when you need to tune your program, then your right here to be the lord of your universe.
The Ebook about how it works internally is in progress: https://www.gitbook.com/book/richdyang/go-my-jvm
Roadmap
- Java class parser
- Interpreter engine
- Class loader delegation
- multi-threading support
- monitor, sleep, wait, notify support
- Bridge JDK native methods
- GC
- JIT
How to run
build and set gopath
❯ cd ~/jago
❯ export GOPATH=`pwd`
❯ export PATH=$PATH:`pwd`/bin
❯ ./build.sh
jago command help
❯ jago -h
_
(_) __ _ __ _ ___
| |/ _` |/ _` |/ _ \
| | (_| | (_| | (_) | version 1.0.0
_/ |\__,_|\__, |\___/
|__/ |___/
Command: jago -h
NAME:
Jago - A simplified Java Virtual Machine for the educational purpose
USAGE:
jago [-options] class [args...]
VERSION:
1.0.0
DESCRIPTION:
A Java Virtual Machine demonstrating the basic features of execution engine, class loading, type/value system, exception handling, native methods etc.
AUTHOR:
Chao Yang <[email protected]>
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--classpath value, --cp value application classpath separated by colon
--log:thread value log level of instruction execution, options: info, debug, trace
--log:classloader value log level of class loading, options: info, debug, trace
--help, -h show help
--version, -v print the version
Run a calendar program
❯ jago --log:thread info -cp . example/Calendar 8 2017
_
(_) __ _ __ _ ___
| |/ _` |/ _` |/ _ \
| | (_| | (_| | (_) | version 1.0.0
_/ |\__,_|\__, |\___/
|__/ |___/
Command: jago --log:thread info -cp . example/Calendar 8 2017
Add new classpath: .
------------------------------------------------------------
August 2017
S M Tu W Th F S
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Run a pyramid program
❯ jago --log:thread info -cp . example/Pyramid
_
(_) __ _ __ _ ___
| |/ _` |/ _` |/ _ \
| | (_| | (_| | (_) | version 1.0.0
_/ |\__,_|\__, |\___/
|__/ |___/
Command: jago --log:thread info -cp . example/Pyramid
Add new classpath: .
------------------------------------------------------------
Pyramid pattern of star in Java :
*
* *
* * *
* * * *
* * * * *
Pyramid of numbers in Java :
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
run a program traversing a tree in the level order
❯ jago --log:thread info -cp . example/TreeLevelOrderTraverse
_
(_) __ _ __ _ ___
| |/ _` |/ _` |/ _ \
| | (_| | (_| | (_) | version 1.0.0
_/ |\__,_|\__, |\___/
|__/ |___/
Command: jago --log:thread info -cp . example/TreeLevelOrderTraverse
Add a new classpath: .
------------------------------------------------------------
___3__
/ \
9 20
/ \
15 7
[[3], [9, 20], [15, 7]]
___1__
/ \
_2 3
/ \
4 5
[[1], [2, 3], [4, 5]]
_______________1______________
/ \
2______ _______3______
\ / \
4 ___5__ 6
/ \
_7 8
/
9
[[1], [2, 3], [4, 5, 6], [7, 8], [9]]
Run a program with exception
❯ jago --log:thread info -cp . test/test_athrow
_
(_) __ _ __ _ ___
| |/ _` |/ _` |/ _ \
| | (_| | (_| | (_) | version 1.0.0
_/ |\__,_|\__, |\___/
|__/ |___/
Command: jago --log:thread info -cp . test/test_athrow
Add new classpath: .
------------------------------------------------------------
prepare to go
Exception in thread "main" test/Exception2: this is exception 2
at test.test_athrow.rest(test_athrow.java:33)
at test.test_athrow.onRoad(test_athrow.java:25)
at test.test_athrow.go(test_athrow.java:20)
at test.test_athrow.main(test_athrow.java:8)
Showcases with example programs
- Print pyramid
jago --log:thread debug --log:classloader debug example.Pyramid
- Show Calendar
jago --log:thread debug --log:classloader debug example.Calendar 8 2017
- Tree Traverse
jago --log:thread debug --log:classloader debug example.TreeInOrderTraverse
jago --log:thread debug --log:classloader debug example.TreeLevelOrderTraverse
- Exception handling
jago --log:thread debug --log:classloader debug test.test_athrow
- Print system properties
jago --log:thread debug --log:classloader debug test.test_system_properties
- Multi-threading
jago --log:thread debug --log:classloader debug test.test_thread
jago --log:thread debug --log:classloader debug example.Multithread
- Thread sleep or wait and interrupt
jago --log:thread debug --log:classloader debug example.SleepInterrupt
jago --log:thread debug --log:classloader debug example.WaitInterrupt
- Java monitor lock with
synchronized
jago --log:thread debug --log:classloader debug example.Counter
- Java wait() and
notify()
,notifyAll()
jago --log:thread debug --log:classloader debug example.ProducerConsumer
trace the execution
log/thread-[name].log
This log file records the each instruction execution and method call hierarchy within a thread context. Set the log level to info to view call hierarchy more clearly.
The blue diamond symbols 🔹 mean pure Java methods while the yellow ones 🔸 mean native methods which is implemented within Jago internally.
The fire symbols 🔥 mean throwing exception (thrown by athrow
bytecode, rethrown if uncaught or thrown by VM internally), the blue water symbols 💧 mean an exception is caught by a method.
- TRACE: log all low level bytecode instructions, method call and exception thrown/caught
- DEBUG: only method call and exception thrown/caught
- INFO: only exception thrown/caught info
log/classloader.log
This log file records the class loading process, including what triggers a class loading and when its class initialization method <clinit> is invoked. The trigger reason can be viewed after a class name.
log/threads.log
This log file records thread creation/exit information and object monitor enter/exit, thread sleep(), wait(), notify() etc.
log/misc.log
Other trivial logs