Chapter 3
Building Jikes RVM
This guide describes how to build Jikes RVM. The first section is an overview of the Jikes RVM build process and this is followed by your system requirements and a detailed description of the steps required to build Jikes RVM.
Once you have things working, as described below, the buildit script will provide a fast and easy way to build the system. We recommend you get things working as described below first, so you can be sure you’ve met the requisite dependencies etc.
3.1 Overview
To avoid problems with the build, make sure that the path to the Jikes RVM source code doesn’t contain any whitespace.
If you run into trouble when building Jikes RVM, don’t hesitate to ask for help on the researchers mailing list.
3.1.1 Compiling the source code
The majority of Jikes RVM is written in Java and will be compiled into class files just as with other Java applications. There is also a small portion of Jikes RVM that is written in C that must be compiled with a C compiler such as gcc. Jikes RVM uses Ant version 1.7.0 or later as the build tool that orchestrates the build process and executes the steps required in building Jikes RVM.
Jikes RVM requires a complete install of ant, including the optional tasks. These are present if you download and install ant manually. Some Linux distributions have decided to break ant into multiple packages. So if you are installing on a platform such as Debian you may need to install another package such as ’ant-optional’.
3.1.2 Generating source code
The build process also generates Java and C source code based on build time constants such as the selected instruction architecture, garbage collectors and compilers. The generation of the source code occurs prior to the compilation phase.
3.1.3 Bootstrapping Jikes RVM
Jikes RVM compiles Java class files and produces arrays of code and data. To build itself Jikes RVM will execute on an existing Java Virtual Machine and compiles a copy of it’s own class files into a boot image for the code and data using the boot image writer tool. The set of files compiled is called the Primordial Class List. The boot image runner is a small C program that loads the boot image and transfers control flow into Jikes RVM.
3.1.4 Class libraries
The Java class library is the mechanism by which Java programs communicate with the outside world. Jikes RVM has configurable class library support, the most mature of which is the the GNU Classpath class library.
For GNU Classpath, the developer can either specify a particular version of GNU Classpath to use. By default the build process will download and build GNU Classpath.
Previous releases of the Jikes RVM had support for the Apache Harmony class library. Jikes RVM no longer supports Apache Harmony because Apache Harmony development was stopped. Work on support for OpenJDK has started but is not yet complete.
3.2 Target Requirements
3.2.1 Architectures
The PowerPC (or ppc) and ia32 instruction set architectures are supported by Jikes RVM.
Intel’s Instruction Set Architectures (ISAs) get known by different names:
- IA-32 is the name used to describe processors such as 386, 486 and the Pentium processors. It is popularly called x86 or sometimes in our documentation as x86-32.
- IA-32e is the name used to describe the extension of the IA-32 architecture to support 8 more registers and a 64-bit address space. It is popularly called x86_64 or AMD64, as AMD chips were the first to support it. It is found in processors such AMD’s Opteron and Athlon 64, as well as in Intel’s own Pentium 4 processors that have EM64T in their name.
- IA-64 is the name of Intel’s Itanium processor ISA.
Jikes RVM currently supports the IA-32 ISA and work on IA32-e is in progress. As IA-32e is backward compatible with IA-32, Jikes RVM can be built and run upon IA-32e processors. The IA-64 architecture supports IA-32 code through a compatibility mode or through emulation and Jikes RVM should run in this configuration. Native IA-64 is not supported.
On PowerPC, only big endian is supported.
3.2.2 Operating Systems
Jikes RVM is capable of running on any operating system that is supported by the GNU Classpath library, low level library support is implemented and memory layout is defined. The low level library support includes interaction with the threading and signal libraries, memory management facilities and dynamic library loading services. The memory layout must also be known, as Jikes RVM will attempt to locate the boot image code and data at specific memory locations. These memory locations must not conflict with where the native compiler places it’s code and data. Operating systems that are known to work include Linux and OS X. At one stage a port to win32 was completed but it was never integrated into the main Jikes RVM codebase. AIX was supported previously but support has been removed due to lack of demand. The same applies for support of Mac OS on PPC.
Note: Current implementation of Jikes RVM implies that system native libraries (like GTK+) have been compiled with frame pointers. Most of Linux distribution have frame pointers enabled in most of the packages, but some explicitly use -fomit-frame-pointer thus producing the library that can’t be used with Jikes RVM.
3.2.3 Support Matrix
The platform support matrix table details the targets that have historically been supported and the current status of the support. The target.name column is the identifier that Jikes RVM uses to identify this target. ??? means that we don’t have regression machines for this platform so the Jikes RVM team can’t guarantee that the target works at a given point in time. We rely on the community to provide a Jikes RVM implementation on these platforms.
target.name | OS | ISA | Address size | Status |
ia32-linux | Linux | IA32 | 32 bits | OK |
ia32-osx | OS X | IA32 | 32 bits | ??? |
ia32-solaris | Solaris | IA32 | 32 bits | ??? |
ia32-cygwin | Windows | IA32 | 32 bits | NYI |
x86_64-linux | Linux | IA32 | 32 bits | OK |
x86_64-osx | OS X | IA32 | 32 bits | ??? |
x86_64_m64-linux | Linux | IA32e | 64 bits | WIP |
x86_64_m64-osx | OS X | IA32e | 64 bits | ??? |
ppc32-linux | Linux | ppc32 (big e.) | 32 bits | ??? |
ppc64-linux | Linux | ppc64 (big e.) | 64 bits | OK |
x86_64 is currently only supported using the legacy 32bit addressing mode and instructions. You need to install the 32-bit versions of the required libraries to build and use the x86_64 configurations.
Note that building on Windows is currently not supported. All previous attempts at building on Windows natively (i.e. without cygwin) used the Apache Harmony classlibrary whose development has been discontinued. Support for building with cygwin is not yet implemented.
3.3 Tool Requirements
Java Virtual Machine Jikes RVM requires an existing Java Virtual Machine that conforms to Java 6.0 such as Oracle JDK 1.6, OpenJDK/IcedTea 6 or IBM SDK 6.0. We also aim to support the Java 7.0-conformant ans Java 8.8-conformant versions of these virtual machines.
Some Java Virtual Machines are unable to cope with compiling the Java class library so it is recommended that you install one of the above mentioned JVMs if they are not already installed on your system. The remaining build instructions assume that a suitable Java Virtual Machine is on your path. You can run java -version to check you are using the correct JVM.
Ant Ant version 1.7.0 or later is the tool required to orchestrate the build process. You can download and install the Ant tool from its Apache homepage if it is not already installed on your system. The remaining build instructions assume that $ANT_HOME/bin is on your path and points to a full Ant installation (i.e. including the optional tasks). You can run ant -version to check you are running the correct version of ant.
C compilers The Jikes RVM build assumes that the GNU Compiler Collection is present on the system. Most modern *nix environments satisfy this requirement. Clang should also work but is untested.
Bison As part of the build process, Jikes RVM uses the bison tool which should be present on most modern *nix environments.
Perl Perl is trivially used as part of the build process but this requirement may be removed in future releases of Jikes RVM. Perl is also used as part of the regression and performance testing framework.
Awk GNU Awk is required as part of the regression and performance testing framework but is not required when building Jikes RVM.
Extra tools recommended for Solaris pkg-get will greatly simplify installing GNU packages on Solaris. Our patches require that GNU patch is picked up in preference to Sun’s. You can create a symbolic link to /usr/bin/gpatch from /opt/csw/bin/patch and make sure /opt/csw/bin is in your path before /usr/bin in order to achieve this.
3.4 Instructions
3.4.1 Defining Ant properties
There are a number of ant properties that are used to control the build process of Jikes RVM. These properties may either be specified on the command line by -Dproperty=variable or they may be specified in a file named .ant.properties in the base directory of the jikesrvm source tree. The .ant.properties file is a standard Java property file with each line containing a property=variable and comments starting with a # and finishing at the end of the line.
The available properties can be grouped into properties that resolve to values and properties that resolve to directories. For properties that resolve to directories, you must make sure that the value of the property resolves to an absolute path. Relative paths aren’t supported by our build system. The path must not contain any whitespace.
Suppose you want to have your build directory in your Jikes RVM directory at mybuilddir (as opposed to target). You would then set build.dir to ${jikesrvm.dir}/mybuilddir. If you wanted to have your build directory in the parent directory of the Jikes RVM directory, you would set build.dir to ${jikesrvm.dir}/../mybuilddir .
Property | Description | Default |
host.name | The name of the host environment used for building Jikes RVM. The host environment defines the paths to the tools used during the build, e.g. the path to the C compiler. The name should match one of the files located in the build/hosts/ directory minus the ’.properties’ extension. | None |
target.name | The name of the target environment for Jikes RVM. The name should match one of the files located in the build/targets/ directory minus the ’.properties’ extension. This should only be specified when cross compiling the Jikes RVM. See Cross-Platform Building for a detailed description of cross compilation. | ${host.name} |
config.name | The name of the configuration used when building Jikes RVM. The name should match one of the files located in the build/configs/ directory minus the ’.properties’ extension. This setting is further described in the section Configuring Jikes RVM. | None |
patch.name | An identifier for the current patch applied to the source tree. See Building Patched Versions for a description of how this fits into the standard usage patterns of Jikes RVM. | “ ” |
require.rvm-unit-tests | If set to true, run unit tests on the built Jikes RVM image. Use with care as it will significantly increase build times for configurations that are compiled using a non-optimizing compiler (see below). | (Undefined, tests are not run) |
require. | Only useful if you want to contribute changes to the Jikes RVM. If set to true, run checkstyle during the build to check for violations of the Jikes RVM Coding Style and Coding Conventions for assertions. | (Undefined, no checks run) |
rvm.debug-symbols | If set to true, build the Jikes RVM with debug symbols for the bootloader code and the code in the bootimage. Note: this is not enabled by default because it causes build failures for configurations that build the bootimage with the optimizing compiler (see RVM-1084). | (Undefined, no symbols built) |
protect.config-files | Define this property if you do not want the build process to update configuration files when auto downloading components. | (Undefined) |
Property | Description | Default |
components.dir | The directory where Ant looks for external components when building Jikes RVM. | ${jikesrvm. |
dist.dir | The directory where Ant stores the final Jikes RVM runtime. | ${jikesrvm. |
build.dir | The directory where Ant stores the intermediate artifacts generated when building the Jikes RVM. | ${jikesrvm. |
components.cache.dir | The directory where Ant caches downloaded components. If you explicitly download a component, place it in this directory. | (Undefined, forcing download) |
At a minimum it is recommended that the user specify the host.name property in the .ant.properties file.
The configuration files in build/targets/ and build/hosts/ are designed to work with a typical install but it may be necessary to overide specific properties. The easiest way to achieve this is to specify the properties to override in the .ant.properties file.
3.4.2 Selecting a Configuration
A configuration in terms of Jikes RVM is the combination of build time parameters and component selection used for a particular Jikes RVM image. The section Configuring Jikes RVM section describes the details of how to define a configuration. Typical configuration names include:
- production: This configuration defines a fully optimized version of the Jikes RVM.
- development: This configuration is the same as production but with debug options enabled. The debug options perform internal verification of Jikes RVM which means that it builds and executes more slowly.
- prototype: This configuration is compiled using an unoptimized compiler and includes minimal components which means it has the fastest build time.
- prototype-opt: This configuration is compiled using an unoptimized compiler but it includes the adaptive system and optimizing compiler. This configuration has a reasonably fast build time.
If a user is working on a particular configuration most of the time they may specify the config.name ant property in .ant.properties otherwise it should be passed in on the command line -Dconfig.name=....
3.4.3 Fetching Dependencies
The Jikes RVM has a build time dependency on the GNU Classpath class library and depending on the configuration may have a dependency on GCSpy. The build system will attempt to download and build these dependencies if they are not present or are the wrong version.
To just download and install the GNU Classpath class library you can run the command ”ant -f build/components/classpath.xml”. After this command has completed running it should have downloaded and built the GNU Classpath class library for the current host. See the Using GCSpy page for directions on building configurations with GCSpy support.
If you wish to manually download components (for example you need to define a proxy, so ant is not correctly downloading), you can do so and identify the directory containing the downloads using -Dcomponents.cache.dir=<download directory> when you build with ant.
3.4.4 Building Jikes RVM
The next step in building Jikes RVM is to run the ant command ant or ant -Dconfig.name=.... This should build a complete RVM runtime in the directory ${dist.dir}/${config.name}_${target.name}. A complete list of documented targets can be listed by executing the command ant -projecthelp.
3.4.5 Running Jikes RVM
Jikes RVM can be executed in a similar way to most Java Virtual Machines. The difference is that the command is rvm and resides in the runtime directory (i.e. ${dist.dir}/${config.name}_${target.name}). See Running Jikes RVM for a list of command line options.
3.5 Building Patched Versions
As part of the research process there will be a need to evaluate a set of changes to the source tree. To make this process easier the property named patch.name can be set to a non-empty string. This will cause the output directory to have the name ${config.name}_${target.name}_${config.variant} rather than ${config.name}_${target.name}, thus making it easy to differentiate between the patched and unpatched runtimes.
The following steps will create a runtime without the patch in dist/prototype_ia32-linux and a runtime with the patch applied in dist/prototype_ia32-linux_ReadBarriers:
% ant -Dconfig.name=prototype -Dhost.name=ia32-linux
% patch -p0 < ReadBarriers.diff
% ant -Dconfig.variant=ReadBarriers -Dconfig.name=prototype -Dhost.name=ia32-linux
% patch -R -p0 < ReadBarriers.diff
The config.variant property is also supported and reported as part of the test infrastructure.
3.6 Cross-Platform Building
The JikesTM RVM build process consists of two major phases: the building of a boot image, and the building of a bootloader. The boot image is built using a JavaTM program executed within a host JVM and is therefore platform-neutral. By contrast, the boot loader is written in C, and must be compiled on the target platform.
Because building the boot image can be time-consuming, you may prefer to build the boot image on a faster machine than the target platform. You may also be porting Jikes RVM to a target platform that lacks tools such or whose development environment is otherwise unpleasant. To cross-build, simply set your host.name and target.name properties to different values.
For example, to build the prototype configuration for AIXTM on a Linux host:
% ant -Dconfig.name=prototype -Dhost.name=ia32-linux -Dtarget.name=ppc32-aix cross-compile-host
The build process is then completed by building just the boot loader on an AIX host:
After the script has completed successfully, you should be able to run Jikes RVM.
The building of the boot loader must occur in the same directory as the rest of the build. This can either be done transparently via a network file system, or by copying the build directory from the first host to the target.
Dependencies
To compile the boot image on the host system you will also need to have built any
dependencies on the target machine and then copied them to the host machine. You
will also need to add an appropriate line into your
${components.dir}components.properties file such as the following (if the target
system was pppc32-linux):
It may be possible to simply build the dependencies on the host machine. Modify the ${components.dir}/components.properties so that the dependency property for target machine maps to the same value as the dependency property on the host machine. This works at the current time but may fail in the future if classpath changes the API between platforms. i.e.
3.7 Primordial Class List
The primordial class list indicates which classes should be compiled and baked into the boot image. The bare minimum set of classes needed in the primordial list includes:
- All classes that are needed to load a class from the file system. The class may need to be loaded as a single class file or out of a jar. Failing this there will be an infinite regress on the first class load.
- All classes that are needed by the baseline compiler to compile any method. Failing this we regress when attempting to compile a method so we can execute it.
- Enough of the core VM services and data structures, and class library (java.*) to support the above. This includes threading, memory management, runtime support for compiled code, etc.
For increased performance and decreased startup time it is possible to include extra classes that are expected to be needed, i.e. the optimizing compiler or the adaptive system. There are some pieces of these components that would be awkward to load dynamically (there’s a core subset of the opt compiler, the classes in the org.jikesrvm.compilers.opt.runtimesupport packages, that must be loaded and fully compiled before any opt-compiled code can be allowed to executed), but it’s theoretically possible to do so.
If you took a full closure of the classes referenced by things that have to be in the bootimage you’d actually end up with a lot more in the bootimage than we currently have. The culprit here would I think mainly be java.* classes that we need in the bootimage, but only use in restricted ways, so we don’t actually have to drag in everything they depend on to meet the ”real” constraints of what has to go in the bootimage. It is unknown how much difference there is between hand-crafted include lists and what an automated tool would discover.
3.8 Using buildit
The buildit script is a handy way to build and test the system. It has countless features and options to make building and testing really easy, particularly in a multi-machine environment, where you edit on one machine and build and test on others. If you really want to get the most of it, take a look at all the options by running:
...or read the script itself.
3.8.1 Examples
Here we just provide a hand full of examples of how it is often used, first for building and secondly for testing (which includes building). Please add to the list if you have other really useful ways of using it. In the examples below, we’ll use three hypothetical hosts: habanero (your desktop), jalapeno (a remote x86 machine) and chipotle (a remote PowerPC machine).
Simple Builds
To build a production image on your desktop, habanero, do the following:
Or equivalently:
To build a production image on the remote machine jalapeno, do the following:
Cross Platform Building
To build a production image on the remote PowerPC machine chipotle, do the following:
Since building on a PowerPC machine can take a long time, you might prefer to build on your x86 machine jalapeno and cross-build to chipotle. In that case you would just do the following:
In each case, buildit figures out the host types by interrogating them and does the right thing (forcing a PPC build on the x86 host jalapeno since you’ve told it you want a build for chipotle, which it knows is PPC). Buildit caches the host information, and will prompt you the first time it encounters a new host.
Full Build Specification
If you want to specify the build fully, you can do something like this:
If you want to specify multiple different GCs you could do:
which would build all three configurations on jalapeno.
Profiled Builds
Jikes RVM has the capacity to profile the boot image and then re-build an optimized boot image based on the profiles. This process takes a little longer, but results in measurably faster builds, and so should be used when doing performance testing. Buildit lets you do this trivially:
Testing
Jikes RVM currently has a notion of a ”test-run”, which defines a complete test scenario, including tests and builds. An example is pre-commit, which runs a small suite of pre-commit tests. It also has the notion of a ”test”, which just specifies a particular set of tests, not the full scenario. An example is dacapo, which just runs the DaCapo test suite (see the testing/tests directory for the available tests).
Running a test run
To run the pre-commit test-run on your host jalapeno just do:
Running a test
To run the dacapo tests against a production on the host jalapeno, do:
To run the dacapo tests against a FastAdaptive MarkSweep build, on the host jalapeno, do:
To run the dacapo and SPECjvm98 tests against production on the host jalapeno, do: