I have always wondered how Common Lisp implements hot-reloading on live functions in multithreaded contexts.
A typical approach used in other languages or debuggers is either to use a dispatch table or to have some NOP bytes at the beginning of every function that could be rewritten into a jmp to the new function definition. In the first case the code incurs a performance penalty for every invocation. In the latter there is no performance hit however the call stack must be kept completely unchanged. This doesn't seem to match the experience one achieves with SBCL on Linux where calls don't seem to be slowed down and one can recompile just some forms in the middle of the stack. It seems that in some way the CL compiler could update also the call stack. The only other language that reaches the same level of interactivity is Smalltalk for which however I know only about of single-threaded implementations. How is CL different from other languages with respect to this? Where can I find more technical details about how hot-reloading is implemented in CL?
Cheers
If one or more threads are executing the old function, then they continue to do that. That object is referenced by those threads and so doesn't become garbage until the last thread stops executing it. Newly issued calls to that function go to the new one through the newly established binding.
ANSI CL allows functions that are in the source file (actually compilation unit) to use more efficient calling; they don't have to go through the global symbol function binding. The idea is that compilation units are replaced at once, rather than individual functions. Call optimizing behavior can be overridden for individual functions by declaim-ing them notinline.