<div dir="ltr">Hi Hayden,<div><br></div><div>Dave's answer covers this pretty well. Neither Orc nor MCJIT currently reason about replacing function bodies. They may let you add duplicate definitions, but how they'll behave if you do that isn't specified in their contracts. They definitely won't replace old definitions unless you provide a custom memory manager that's rigged to lay new definitions down on top of old ones.</div><div><br></div><div>I suspect that existing clients of MCJIT have tackled this by adding thread safety into their wrappers around MCJIT, or into the JIT'd code itself, but I'm just guessing. (CC'ing Keno and Philip, in case they have insights). </div><div><br></div><div>I think this would be cool to build in to Orc though. Two quick thoughts:</div><div><br></div><div>(1) Replacing function bodies at the same address is impossible if the function is already on the stack: You'd be replacing a definition that you're later going to return through. So, if you want to replace functions at the same address you'll have to have some sort of safe-point concept where you know the function you want to replace isn't on the stack.</div><div><br></div><div>(2) Replacing function bodies at the same address isn't the only way to avoid the overhead of a trampoline. I haven't implemented this yet, but I really want to add llvm.patchpoint support to Orc. In that case you can lay down your replacement definition at a different address, update all your callsites, then delete your old definition after you're done executing it. Relative to using trampolines this lowers your execution cost (calls are direct rather than indirect), but increases your update cost (you have to update many callsites, rather than a single trampoline). </div><div><br></div><div>Out of interest, why the desire to avoid trampolines? They do make life a lot easier here. :)</div><div><br></div><div>Cheers,</div><div>Lang.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 18, 2015 at 3:13 AM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">[+Lang, keeper of JITs, designer of ORCs]<div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Tue, Mar 17, 2015 at 1:27 AM, Hayden Livingston <span dir="ltr"><<a href="mailto:halivingston@gmail.com" target="_blank">halivingston@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I've been playing with OrcJIT a bit, and from the looks of it I can (like in the previous JIT I suppose?) ask for a function to be re generated.</div><div><br></div><div>If I've given the address of the function that LLVM gave me to an external party, do "I" need to ensure thread-safety?</div><div><br></div><div>Or is it safe to ask OrcJIT to re generate code at that address and everything will work magically?</div></div></blockquote></span><div><br>As I understand it, Orc won't regenerate the function at the same location unless your memory manager returns the same memory twice - so if you know you've successfully migrated all callers off a certain chunk of allocated memory, you might be able to recycle it back into Orc (but I think on MacOS, the way page permissions work, this would be impossible - once a memory page is marked executable, it's no longer writable and can't be set back - you need a new page).<br> </div><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I'm thinking it won't because it's quite possible some thread might be executing code, and we'll be asking LLVM to write bytes there.<br></div><div><br></div><div>How does one generally go do such updates? I'm looking for some guidance without adding a trampoline in front of it. Do runtimes that support re-generation of code have an if check or something before entering the method?</div></div></blockquote></span><div><br>Without a trampoline you're probably going to have to be constrained in some other ways - possibly (& I'm really out of my depth at this point) the kind of safe/pause points used for GC - but perhaps more constrained than that, such that you have safe places where your JIT'd code (or at least the replaceable functions) isn't running.<br><br>But again, still depends on platform - writing to executable memory isn't possible on MacOS so far as I know (as mentioned above) so there would be no way to replace a function there without a trampoline or at least a global variable to load/jump to.<br><br>- David<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div>
</blockquote></div><br></div>