The deceptively simple foundation of dynamic code generation within a C/C++ framework has already been covered in another question. Are there any gentle introductions into topic with code examples?
My eyes are starting to bleed staring at highly intricate open source JIT compilers when my needs are much more modest.
Are there good texts on the subject that don’t assume a doctorate in computer science? I’m looking for well worn patterns, things to watch out for, performance considerations, etc. Electronic or tree-based resources can be equally valuable. You can assume a working knowledge of (not just x86) assembly language.
Well a pattern I’ve used in emulators goes something like this:
This is a simplification, but the idea is there. Basically, every time the engine is asked to execute a ‘basic block’ (usually a everything up to next flow control op or whole function in possible), it will look it up to see if it has already been created. If so, execute it, else create it, add it and then execute.
rinse repeat 🙂
As for the code generation, that gets a little complicated, but the idea is to emit a proper ‘function’ which does the work of your basic block in the context of your VM.
EDIT: note that I haven’t demonstrated any optimizations either, but you asked for a ‘gentle introduction’
EDIT 2: I forgot to mention one of the most immediately productive speed ups you can implement with this pattern. Basically, if you never remove a block from your tree (you can work around it if you do but it is way simpler if you never do), then you can ‘chain’ blocks together to avoid lookups. Here’s the concept. Whenever you return from f() and are about to do the ‘update_instruction_pointer’, if the block you just executed ended in either a call, unconditional jump, or didn’t end in flow control at all, then you can ‘fixup’ its ret instruction with a direct jmp to the next block it’ll execute (cause it’ll always be the same one) if you have already emited it. This makes it so you are executing more and more often in the VM and less and less in the ‘execute_block’ function.