JIT or Just-in-time Compilation is a technique to improve the performance of software that compile to byte code, translating the byte code to machine code at runtime. In computing, Just-in-time Compilation (JIT) is also known as dynamic translation as compilation is done during execution of a program at run time rather than prior to execution. In our previous article on Big Data and R Programming Language, we wrote that :
The package jit provides JIT-compilation (Just-in-time compilation) and the package compiler offers a byte-code compiler for R. The packages snow, multicore, and parallel provide parallelism for R. The package ff saves memory by storing data on disk. The data structures behave as if they were in RAM. The package ffbase provides basic statistical functions for ˜ff™.
So, this article, explains the Just-in-time Compilation (JIT) part in general.
What is JIT (Just-in-time) Compilation?
As we said at the beginning of this article that in computing, compiling at runtime is also known by the acronym, JIT, which means Just-in-time Compilation), which in turn is also known as dynamic translation, is a technique to improve the performance of software systems that compile to bytecode, consisting of translation the bytecode to machine code at runtime. The run-time compilation is constructed from two previous ideas related to runtime environments : bytecode compilation and dynamic compilation.
In a system using bytecode compilation such as Smalltalk, Perl, GNU CLISP or early versions of Java; the source code is translated to an intermediate code called bytecode . The bytecode is not the machine code of any particular computer and therefore can be portable between different architectures. The bytecode is then interpreted and executed by a virtual machine.
A dynamic compilation environment is one in which the compiler can be used at runtime. For example, most systems with Lisp Commons have a feature that allows to compile compile new functions created during program execution. Although advantageous in the purification is interactive, dynamic compilation is less useful in a system which requires unattended operation. This method is most common in emulators in modern commercial and often require a lot of speed, such as QEMU and VirtualPC (PC) or Executor (Macintosh 68k).
The bytecode is deployed on the target system. When this code is executed, the runtime compiler translates it into native machine code. This can be done at the file level (program) or functions being compiled in the latter case the code for a function just when user will run (hence the name of just-in-time). The aim is to combine many of the advantages of compiling to native code and bytecode: most of the “heavy work” to process the original source code and perform basic optimizations are performed at the time of compiling to bytecode, long before the deployment : the compilation to machine code of the program is much faster than starting from the source code. The deployed bytecode is portable, unlike the machine code for any specific architecture. Dynamic compilers are easier to write, the bytecode compiler performed much of the work.
JIT (Just-in-time) Compilation : Behind the Scene
JIT (Just-in-time) Compilation fundamentally uses executable data and thus poses security challenges and possible exploits.
Upon emulating the CPU, the program translates the software emulated machine code into native machine code emulator and writes a cache and execute permissions [usually in UNIX or POSIX compatible systems, this permission is assigned by the mprotect ()) function.]
Translation stops when any instruction is to cause a change in the program counter, as an interruption, a jump instruction or a subroutine call and is interpreted as a routine return to the compiler or other program tasks. Then the emulator executes the code contained in the cache.
The advantage of this method is that if the cache size is large, the emulator does not need to recompile the code, which greatly increases the speed. However, problems arise when the emulated program writes the code, and it is necessary to recompile the code, unless the emulated code is only readable, for example on UNIX systems with protected memory.
The term “Just-in-time compilation” was borrowed from the manufacturing term “Just in time” and popularized by Java, with James Gosling using the term from 1993. Currently JITing is used by most implementations of the Java Virtual Machine, as HotSpot builds on, and extensively uses, this research base.
The HP project Dynamo was an experimental JIT compiler where the ‘bytecode’ format and the machine code format were the same; the system turned HPA-6000 machine code into HPA-8000 machine code. Counter-intuitively, this resulted in speed ups, in some cases of 30% since doing this permitted optimizations at the machine code level, for example, in-lining code for better cache usage and optimizations of calls to dynamic libraries and many other run-time optimizations which conventional compilers are not able to attempt. Also, there are Java implementations that combine an AOT (ahead-of-time) compiler with either a JIT compiler (Excelsior JET) or interpreter (GNU Compiler for Java.)
JIT spraying is a class of computer security exploits that use JIT compilation for heap spraying “ the resulting memory is then executable, which allows an exploit if execution can be moved into the heap.