I'm not getting the distinction between bytecode interpretation and JIT compilation. I've read many, many, many, many postings and articles on this topic.
One Javaworld.com article that I found on Java compilers provides this explanation:
The simplest form of bytecode compilation is called interpretation. An interpreter simply looks up the hardware instructions for every bytecode instruction and sends it off to be executed by the CPU.
You could think of interpretation similar to using a dictionary: for a specific word (bytecode instruction) there is an exact translation (machine code instruction).
So consider this example of bytcode interpretation (from the same article):
A. Java application code:
static int add7( int x ) {
return x+7;
}
B. javac
compiler compiles the program from A into Java byte code
iload0
bipush 7
iadd
ireturn
C. java
interpreter translates the bytecode from B into native machine instruction code (e.g. Intel x86). Below is some assembly code representing machine code.
lea rax,[rdx+7]
ret
My understanding is that going from step B to step C requires compiling, right? The definition of a compiler is a software component that translates from one (high level) language to another (lower level) language. That is exactly what is going on between step B to C.
So, assuming that my understanding is correct, then what is the major difference between interpreting (which is compiling) and JIT compiling? I get that the JIT compiler can do things like add performance counters and optimizations (e.g. inlining), but if we leave those out, aren't the interpreter and the JIT compiler doing the same thing?