Ask HN: How do VMs hot swap native code?
* The JVM compiles bytecode to native code on the fly
* Lisp implementations like SBCL take an expression entered at the REPL, compile them to assembly, and insert it into the running process
How does this work? I think I should be looking at the internals of some scheme implementation, but am not sure where to start.
3 comments
[ 3.0 ms ] story [ 15.2 ms ] threadGoogle V8 is fairly well documented, but I think it is very complicated.
JVM is a beast. Perhaps the openJDK project has some useful information.
Personally, I would look at Racket Scheme: https://racket-lang.org/ The main reason being is that there are several papers that describe how it is done internally.
A simple example that could get you started may be found at: https://eli.thegreenplace.net/2013/11/05/how-to-jit-an-intro...
In short, the answer is to think of everything as an object. A pointer is an object, a block of compiled code is an object, a return address is an object, an execution context is an object and so on. All these objects are related to each other in one huge object graph that the VM keeps track of. For example, if one code object (such as a function) calls another, then the VM views each address in each assembler CALL instruction as one pointer, pointing from one function to the other. So if foo calls bar and bar is recompiled, a new code block which we'll call bar' would be inserted at the end of the code heap and then each CALL instruction in foo would be updated to point to bar' instead.
This can get quite complicated if another execution context is running baz which was called from bar. How can we ensure that it returns to bar' instead of bar? We would have to go through the stack of the execution context and update all return addresses stored in it so that they point to bar' instead of bar.
Of course all this has to be done as efficiently as possible so VM implementors use huge amounts of bit fiddling tricks which obscures what the code is doing...