I'm working on a VM (and a scripting language for it) that I plan to implement JITing for. I'm only working on the "plumbing" of it now, but I don't want the JIT compiler to be an afterthought. However, while I understand the fundamentals of it, I'm a bit confused on what exactly the JIT should do.
There are two ways I could think of it being implemented:
- Translate the bytecode into "proper" x86 just like any compiler would, thus eliminating the interpreter/VM part.
- Translate the bytecode into x86 that calls VM functions to tell it what to do thus eliminating the interpreter's opcode decoding step and going straight to calling the internal VM functions.
The first method would be difficult to implement simply because it requires knowledge on not only building a full-blown compiler, but being able to compile a high-level language that relies normally on VM functionality to be compiled into native code.
The second method would be much simpler to implement as you're not actually compiling the program, you're just dynamically creating a list of C function calls (to the internal VM) with corresponding operands with x86 instructions to call in the same order that would've otherwise require an interpreter to "decode".
However, while the second clearly seems more sane to implement, I'm not too sure how much more (or less) it would effect the performance of the program. What direction should I aim for? Any notable pros and cons?