Interesting article. I'm writing a toy trace compiler at the moment and implementing side exits brings up many of the same, rather irritating problems.
Would be fun to try to compare this with a decent GC and see what the difference is likely to be. The reason why I say this is because Javas default GC pre-allocates a heap (a Java allocation is mostly just bumping a pointer), and since it "frees" memory by copying survivors to a new space you also avoid fragmentation.<p>If it turns out that what you mostly pay for, when using a GC, is that collection happens at one point in time instead of incrementally, then Go's plan for the evolution of their GC just became a lot more interesting.
It seems to me that we should not make the problem more complicated than necessary. If you're debugging code written in Javascript, you may assume that the JIT optimizer is correct. If you need special features enabled (such as stack traces, etc.), then just pepper the code that <i>enters</i> the JIT with logging instructions, etc.<p>There should never be a need to completely disable the JIT optimizer, except perhaps to debug the JIT itself.