Bebbo's Virtual Machine
I did start this project since I was unsatisfied with the available Java virtual machines:
- Why does even the tiniest program require 7MB memory or even more?
- Why are the JVMs so huge?
I also tried some other solutions, e.g. the GNU gcj compiler (available for Windows at http://www.cygwin.com). This works fine unless the HelloWorld.java results in an executable of 2MB size.
If you want to have something done right, you have to do it yourself
The goals to reach are
- create executables from Java code
- with small size
- and adequate performance
Since this a bit more than for Saturday afternoon, I defined my first milestone
Milestone 1
- define a garbage collector (gc) mechanism
- define an exception handling (eh) mechanism
- define the native code support
- define working assembler code from Java files which fits gc and eh
- program the startup code
- program the basic Java classes
- program the basic native methods (e.g. write to console)
- program a Java to assembler converter for most opcodes
- compile, assemble and link the HelloWorld
The code
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello world!");
}
}
results into an executable of 27.136 bytes. Woot!
Milestone 2
- implement a "destack" algorithm which converts the stack orientated generated assembler code into better code
- implement more native methods for full file I/O
- programm some examples usable as benchmark to compare the speed of the implementations. The current benchmark is available here
program | V1 size | V1 speed | V2 size | V2 speed | JVM 1.5 speed | gcj speed
|
HelloWorld | 27.136 | - | 26.624 | - | - | -
|
Test add | 30.208 | 56380 | 29.184 | 100512 | 84484 | 212273
|
These results are not bad for the first shot! The peformance is half of gcj with all optimizations, which is much faster than I expected! And the functionality is even good enough for first simple utilities, which requires the gc only at program end.
Milestone 3
- implement more optimizations
- complete code generation for all opcodes
current measurements
UPDATED
Test | BVM speed | JVM 1.5 speed | gcj speed
|
return 0 | 230910 | 98667 | 224542
|
add | 180219 | 91480 | 195843
|
multiply | 149357 | 89095 | 197152
|
add array | 117054 | 73929 | 127408
|
loop10000 | 79 | 35 | 88
|
biginteger multiply | 4753 | 2815 | 2373
|
biginteger modulo | 3976 | 3429 | 4961
|
With more optimizations the code is coming close to gcj, for more complex code (less possible optimizations) the difference to gcj is even less. The performance is always better than the JVM 1.5 classic mode. This is a good base to add the missing features, but there are still some more possible optimizations.
Milestone 4
- added Threads to BVM.
- added an implementation synchronized methods and synchronized statement
The implementation is not yet tuned for performance but tuned to be resource friendly. Since every Java object can be used with synchronized the mutex objects are created when necesarry. Let's look forward for some benchmark results. The good news is the small impact on size with all that new stuff. HelloWorld uses now 29.184 bytes.
Future
- enable garbage collector
- enable exception handler
- program a socket implementation
- support notify() / notfiyAll()
- support dynamic class loading
... stay tuned
rev: 1.14