I had not heard of JIT compilers that don't actually create code native to the CPU and don't execute it directly on the CPU. My understanding is that in absence of generating and executing native code directly on the CPU - the JIT would be a regular interpreter. Wikipedia seems to agree with me on this FWIW :) Out of curiosity - do you have any examples of JIT use cases that differ from "compile to native code and execute just in time, directly on the CPU"?
Quote:
"JIT compilers are a novel idea: take some code in an “intermediate form”, and, given some heuristics, compile it into a “more native” representation,"
Note: They write "more native" representation.
Quote:
"Conversely, in JRuby, the source format is the JRuby AST, and the destination format is Java bytecode. Perhaps the most fascinating aspect of the JRuby JIT compiler is that it benefits from both the initial compilation into Java bytecode, and then later, when Java may attempt to translate the JRuby-generated bytecode into native machine instructions."
So the JRuby guys have a multi-staged JIT:
JRuby AST => Java Bytecode => native
Depending on how the program is executed at runtime some parts of it will stay in JRuby AST, more interesting parts of the code will be transformed to Java Bytecode and the Hotspots may end up as native code.
- A compiler takes some input, does some specific stuff to it (like lexical analysis and parsing), and writes some output ("code generation")
- An interpreter takes some input, does some specific stuff to it (like lexical analysis and parsing) and executes it
- A JIT compiler is a compiler, like above, but it does its thing on the fly, as you go. This means it has to tie into the execution model on some level, to know which parts of the program need translation.
A component that takes a program and executes it could correctly be described as an interpreter, but it might also be correctly separated into a JIT compiler (that spits out an intermediate representation) and an interpreter (for the intermediate representation, not the original source).
I have no example of such a beast, but it is concievable, no? :)
A JIT compiler is a bit more. When the program is executed the JIT may decide to just interpret the code of a function and not compile it at all. It can selectively transform parts of the code to a better representation. Code that is executed frequently may be compiled by the JIT into a more suitable representation. There are also multi-staged JITs (JRuby - see my other comment).