Anyway, the main reason why I don't believe VMs/JIT will ever catch native code in terms of speed is because it's a bit like the telephone game. In a C program, you more or less tell the CPU what to do, step by step (assuming the compiler is smart enough not to do really stupid things). You can even use custom ASM in C, you can use registers for variables, and so on.
For Java, the compiler will translate stuff to virtual code (one step) then the JIT will translate that code in native code (another step). The more steps you have in a process the least likely it is for the final code to do things the way you want it to be done