On-stack replacement (OSR) is a popular technique used by just in time (JIT) compilers.
A JIT can use OSR to transfer from interpreted to compiled code in the middle of execution, immediately reaping the performance benefits of compilation.
This technique typically relies on loop counters, so it cannot be easily applied to languages with unstructured control flow.
It is possible to reconstruct the high-level loop structures of an unstructured language using a control flow analysis, but such an analysis can be complicated, expensive, and language-specific.
In this paper, we present a more lightweight strategy for OSR in unstructured languages which relies only on detecting backward jumps.
We design a simple, language-agnostic API around this strategy for language interpreters.
We then discuss our implementation of the API in the Truffle framework, and the design choices we made to make it efficient and correct.
In our evaluation, we integrate the API with Truffle’s LLVM bitcode interpreter, and find the technique is effective at improving start-up performance without harming warmed-up performance.