The RVM is started up by a boot program written in C. This program is responsible for
- registering signal handlers to deal with the hardware errors generated by the RVM
- establishing the initial virtual memory map employed by the RVM
- mapping the RVM image files
- installing the addresses of the C wrapper functions which are invoked by the runtime to interact with the underlying operating system into the boot record of at the start of the RVM image area
- setting up the JTOC and TR registers for its
- switching the pthread into the bootstrap Java stack running the bootstrap Java method in the bootstrap Java thread
At this point all further initialization of the RVM is done either in Java or by employing the wrapper callbacks located in the boot record.
The initial bootstrap routine is
VM.boot(). It sets up the initial thread environment so that it looks like any other thread created by a call to Thread.start() then performs a variety of Java boot operations, including initialising the memory manager subsystem, the runtime compiler, the system classloader and the time classes.
The bootstrap routine needs to rerun class initializers for a variety of the runtime and Classpath classes which are already loaded and compiled into the image file. This is necessary because some of the data generated by these initialization routines will not be valid in the RVM runtime. The data may be invalid as the host environment that generated the boot image may differ from the current environment.
The boot process the enables the Java scheduler and locking system, setting up the data structures necessary to launch additional threads. The scheduler also starts the
FinalizerThread and multiple garbage collector threads (i.e. multiple instances of
Next, the boot routine boots the the JNI subsystem which enables calls to native code to be compiled and executed then re-initialises a few more classes whose init methods require a functional JNI (i.e.
Finally, the boot routine loads the boot application class supplied on the rvm command line, creates and schedules a Java main thread to execute this class's main method, then exits, switching execution to the main thread. Execution continues until the application thread and all non-daemon threads have exited. Once there are no runnable threads (other than system threads such as the idle threads, collector threads etc) execution of the RVM runtime terminates and the rvm process exits.
The RVM divides its available virtual memory space into various segments containing either code, or data or a combination of the two. The basic map is as follows:
The bottom segment of the address space is left for the underlying platform to locate the boot program (including statically linked library code) and any dynamically allocated data and library code.
RVM Image Segment
The next area is the one initialized by the boot program to contain the all the initial static data, instance data and compiled method code required in order for the runtime to be able to function. The required memory data is loaded from an image file created by an off line Java program, the boot image writer.
This image file is carefully constructed to contain data which, when loaded at the correct address, will populate the runtime data area with a memory image containing:
- a JTOC
- all the TIBs, static method code arrays and static field data directly referenced from the JTOC
- all the dynamic method code arrays indirectly referenced from the TIBS
- all the classloader's internal class and method instances indirectly referenced via the TIBS
- ancillary structures attached to these class and method instances such as class bytecode arrays, compilation records, garbage collection maps etc
- a single bootstrap Java thread instance in which Java execution commences
- a single bootstrap thread stack used by the bootstrap thread.
- a master boot record located at the start of the image load area containing references to all the other key objects in the image (such as the JTOC, the bootstrap thread etc) plus linkage slots in which the booter writes the addresses of its C callback functions.
RVM Heap Segment
The RVM heap segment is used to provide storage for code and data created during Java execution. The RVM can be configured to employ various different allocation managers taken from the MMTk memory management toolkit.