Tuesday, December 09, 2008

Maxine

Maxine is an exciting virtual machine research project conducted at Sun Labs. The Maxine VM is a metacircular Java VM, i.e., it is implemented (almost) completely in the Java programming language. As all of the high-level abstractions available in Java can be used to implement the VM, the code is rather well accessible, albeit still very complex, given the complexity of the domain.

The Maxine source code is available under the GPL 2.0. The code is very well organised and modular: all of the VM's features are encapsulated behind well-defined interfaces, whose concrete implementations are chosen at VM build time. This allows for circumventing the need to employ a preprocessor: the code thus behaves very well in an IDE.

Its metacircularity aside, which alone does not set Maxine apart from other JVM implementations like IBM's Jikes RVM, Maxine comes with a tool called the Maxine Inspector that makes it truly unique. The Inspector is actually a debugger, but an extremely sophisticated one. It allows for analysing every single aspect of the running VM in a most comfortable way. For instance, double clicking on the value stored in a processor register will, provided the register contains a valid object pointer, yield an object inspector (much in the fashion of Smalltalk) providing all kinds of information on that particular instance. It is also possible to trace back JIT-compiled machine code instructions to the corresponding byte code and even application or JVM source code.

In a nutshell, this is how I'd like to do VM debugging and development.

There are some things about Maxine that might be called downsides, but it's actually not that bad. First and foremost, Maxine requires powerful hardware. Maxine is, at the moment, restricted to 64-bit platforms. To make development and debugging comfortable, more than one 64-bit core and some 4 GB of memory are required. As for the operating system, Solaris is the one on which things are most smooth; Mac OS X is quite OK, and Linux is extremely problematic. (One might consider this a valid reason to start using Solaris.)

I intend to do some work with Maxine, and would like to share what I learn. Today, I'd like to start with a description of how I made it compile and run for me.

Hardware, Operating System, and Software

Happily, my employer equipped me with a dual-core 64-bit machine with 4 GB RAM and enough hard disk space to allow for a coexistence of Linux, Windows, and Solaris. I chose to work on Maxine on Solaris for two reasons: it's the recommended platform for Maxine, and I'm curious.

Thanks to a very helpful and capable student sysadmin (thanks, Tobias!), making the three operating systems coexist was possible in almost no time. Installing most of the required software on Solaris is also easy: a 64-bit Java and the NetBeans IDE can simply be installed using the Solaris package manager.

Mercurial is the source code management system to use. It is available for separate download and can be installed like this (provided pfexec is configured correctly):

bzip2 -d SUNWmercurial-0.9.5-i386.pkg.bz2
pfexec pkgadd -d SUNWmercurial-0.9.5-i386.pkg

The instructions below are based on those available from the Maxine home page, and have been adapted to fit the use of Mercurial. Moreover, some steps I had to do to make things work in my own environment are mentioned.

Getting the Maxine Sources

The Maxine Mercurial repository is hosted at http://kenai.com/projects/maxine. More particularly, the three different repository URLs are as follows:

https://kenai.com/hg/maxine~maxine
https://kenai.com/hg/maxine~extras
https://kenai.com/hg/maxine~netbeans-inspector

Importing the sources—and the NetBeans projects contained therein—in NetBeans is simple. For each of the above locations, the following steps need to be taken:
  1. Select Versioning -> Mercurial -> Clone Other...
  2. Enter the corresponding URL and click "Next >".
  3. Confirm the push and pull paths by clicking "Next >" once more.
  4. Leave the "Scan for Netbeans Projects after Clone" checkbox ticked, and confirm the destination directory by clicking "Finish".
Once this has been done for all three locations (note that maxine~extras appears to be empty), NetBeans will show a list of projects and some warnings about reference problems due to projects that could not be found. This can easily be mended by right-clicking on each of the problematic projects, choosing "Resolve Reference Problems..." from the context menu, and assigning the correct projects accordingly.

Compiling MaxineNative

The MaxineNative project represents the boot image loader implemented in C, which cannot be compiled from within NetBeans right now.

To make this compile, a single header file from the OpenSolaris code base is required; it is libproc.h. This file needs to be placed in the Native/inspector/solaris directory. (Be careful to use the right link; I managed to download a HTML representation of the file linked-to from the Maxine home page, which obviously would not compile. Quite embarrassing. The link given here is the one to the unformatted C source code.)

It is important to use the right C compiler to compile MaxineNative. By default, OpenSolaris (which is the distribution I'm using) installs the GNU C compiler, which cannot be used. To get the ANSI C compiler, the sunstudioexpress package can be installed—that's probably a bit too much as it also contains Fortran and C++ compilers, but this is what I did.

Another important step is to adjust the PATH environment variable to make sure the ANSI C compiler is executed instead of the GNU C compiler.

export PATH=/usr/bin:/usr/gnu/bin:/usr/X11/bin:/usr/sbin:/sbin

By default, /usr/gnu/bin comes before /usr/bin, which leads to GCC taking priority over CC, which in turn leads to interesting error messages when compiling MaxineNative.

Running Hello World

Of course, Maxine comes with a Hello World application. Once the VM is properly built according to the instructions from the home page and above, the binary can be found in Native/generated/solaris/maxvm; the directory could be added to the PATH. The Hello World application is located in VM/test/util/HelloWorld.java, which can simply be compiled from the command line using javac.

From the VM/test directory, the application can be run like this:

../../Native/generated/solaris/maxvm -cp . util.HelloWorld

No comments:

Post a Comment