A recent software development allows applications to be easily implemented on various types of computer systems that have different processors. This is achieved by executing the applications within a virtual runtime environment. In one environment, source code may be written using one of several computer languages, such as C#. The source code is then compiled into an intermediate language assembly. An application created using one or more of the intermediate language assemblies is referred to as a “managed” application. In order for the managed application to execute on a particular computer system, its associated intermediate language (IL) assemblies undergo further processing.
This additional processing may be performed using one of several different techniques. One technique, commonly referred to as Just-In-Time (JIT) compilation, performs the conversion of the IL assemblies into the executable code during runtime. Another technique, commonly referred to as pre-JIT compilation, performs the conversion of the IL assemblies into the executable code before runtime. The pre-JIT compilation converts the IL assemblies into a native image that is specific to the processor on which the managed application will run. Thus, the native image contains instructions that are ready for execution. While the JIT compilation and the pre-JIT compilation produce equivalent executable instructions, the pre-JIT compilation provides faster execution because the instructions are ready for execution once the native image is loaded.
The pre-JIT technique is similar to the traditional build procedure for creating binaries. In the traditional build procedure, source code is compiled into an object file for a specific processor or operating environment. Thus, for each different computer environment/processor, the traditional source code is re-compiled for that particular environment/processor. One or more object files may then be linked to make the executable binary. The creation of the executable binaries for each type of computer environment/processor is typically performed in a build lab. The different binaries are then distributed to the computers based on their environment/processor. While this works, this traditional build procedure makes it difficult to distribute code over a diverse network, such as the Internet.
The above-mentioned intermediate language assemblies do not have this distribution problem. The same IL assembly can be distributed to different computer environments/processors. Even though the pre-JIT technique creates a native image particular to one computer environment/processor, the pre-JIT technique still preserves the mobility aspect because the pre-JIT technique is performed by the target computer.
However, traditional applications created using the traditional build process offer advantages not available to managed applications, namely the ability to share data and have constant data. In traditional applications, constant data sections are utilized which are shareable to all running copies of a program or library. The constant data sections are initialized at compilation time. Thus, once the constant data is read from disk, disk cache, or the like, the constant data is available for all the running copies of the program or library.
Unfortunately, managed applications can not embed constant data into their executables or share data between managed applications. Instead, managed applications create the necessary constant data structures when the managed application is first loaded for execution. The constant data structures, along with all the other data for the managed application, are placed on the memory heap so that a garbage collection process can manage the memory for that particular managed application.
Thus, until now, there has not been a satisfactory solution for sharing objects between applications executing in a virtual runtime environment.