The overall structure of Jupiter is depicted in Figure 1. In the center is the ExecutionEngine, the control center of the JVM, which decodes the Java program's instructions and determines how to manipulate resources to implement those instructions. The resources themselves are shown as ovals, and include Java classes, fields, methods, attributes, objects, monitors, threads, stacks and stack frames (not all of which are shown in the diagram).
The responsibility for managing each resource is delegated by the ExecutionEngine to a particular Source class, each shown as a rectangle within the pie slice that surrounds the resource it manages. The Sources insulate the ExecutionEngine from the details of how resources are managed. Sources share a simple, uniform interface: every Source class has one or more get methods which return an instance of the appropriate resource. Each get method has arguments specifying any information needed by the Source to choose or allocate that resource, and the Source is responsible for deciding how the resource should be created, reused, or recycled.
An incarnation of Jupiter, then, is constructed by assembling a number of Source objects in such a way as to achieve the desired JVM characteristics, a scheme referred to as a building-block architecture [13]. As each Source is instantiated, its constructor takes references to other Sources it needs in order to function. For instance, as shown in Figure 1, the ObjectSource makes use of a MemorySource, so the ObjectSource constructor would be passed a reference to the particular MemorySource object to which it should be connected. The particular Source objects chosen, and the manner in which they are interconnected, determines the behaviour of the system.
The assembly of a JVM out of Jupiter's Source objects is much like the manner in which UNIX command pipelines allow complex commands to be constructed from discrete programs: each program is ``instantiated'' into a process, and each process is connected to other processes, via pipes, as described by the command syntax; once the process-and-pipe structure has been assembled, data begins to flow through the structure, and the resulting behaviour is determined by the particular choice of programs and their interconnections. Likewise, an incarnation of Jupiter is first constructed by instantiating and assembling Sources. Once the JVM is assembled, the Java program begins to flow through it, like data through the command pipeline. The behaviour of the JVM is determined by the choice of Source objects and their interconnections.
Figure 2 shows part of a typical running incarnation of Jupiter, consisting of interconnected Source objects through which the resources of the executing Java program flow. Also depicted is a typical collection of resource objects. In particular, the Context object represents the call stack for an executing Java program. To begin execution, a Context is constructed and passed to an ExecutionEngine, which sets the rest of the JVM in motion to interpret the program. From the Context object, the MethodBody object can be reached, which possesses the Java instructions themselves. By interpreting these instructions and manipulating the appropriate sources and resources in the appropriate way, Jupiter is able to perform the indicated operations, thereby executing the Java program.