[LLVMdev] On-Stack Replacement & Code Patching

Reid Kleckner rnk at mit.edu
Wed Mar 10 13:49:43 PST 2010


On Wed, Mar 10, 2010 at 3:11 PM, Nyx <mcheva at cs.mcgill.ca> wrote:
>
> I am interested in writing a JIT that makes use of on-stack replacement. This
> essentially means that the JIT must be able to compile new versions of
> already compiled functions (eg: more optimized versions) and ensure that the
> code for the new functions is executed. I was wondering if LLVM offers any
> support for this.
>
> Suppose a function f calls a function g, and f is recompiled while g is
> running, I would need to be able, when returning from g to f, to jump to the
> updated code for f. So, one way to implement this would be to insert a jump
> after every call in the body of the old function f, that jump to the
> corresponding point in the body of the new function. This would require me
> to overwrite some of the code of f. If LLVM has no direct support for this,
> I could potentially create auxiliary "call handler" functions which can do a
> long jump to the proper code on return.
>
> So what I would like to know is:
>
> 1. Does LLVM support code patching? By this, I mean overwriting some
> instructions

You can call recompileAndRelinkFunction, which patches the stub of a
function with a jump to the new function body.

> 2. Does LLVM support long jumps?

You can use a tail call to accomplish this.

> 3. Has anyone here implemented code patching or on-stack replacement in
> LLVM?

Our plan in unladen swallow for recompilation is to to generate a new
function each time.  We don't want to worry about other threads that
may be executing machine code while we're patching it, so the simple
design is that every snippet of code has an object that owns it.  Each
frame executing that code increments the refcount before entering it,
and decrefs after exit.  This is basically the call wrapper that
you're talking about.

This doesn't do on-stack replacement, but it may help you solve some
of your problems.

>
> Another potential issue is that if I recompile some function, I would
> ideally want to keep the same stack representation for both. This could
> potentially be quite tricky. Any advice on how to go about this?

I'm pretty sure there's no way to guarantee that the stack frame
representation in LLVM is going to be the same.  Your best bet would
be to maintain your own representation of the stack frame on the side
which you can save to and restore from on your entry and exit code
paths.  If you have an interpreter that you're interfacing with, you
will probably need to do this already.

Reid



More information about the llvm-dev mailing list