<div dir="ltr">Hi Sanjoy,<div><br></div><div>I hadn't started thinking about deoptimization yet. That makes perfect sense though.</div><div><br></div><div>> So this is the Patches Welcome(TM) part. :P<br></div><div><br></div><div>Yep. :)</div><div><br></div><div>Cheers,</div><div>Lang.<br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 20, 2015 at 9:39 AM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On Thu, Mar 19, 2015 at 3:28 PM, Lang Hames <<a href="mailto:lhames@gmail.com">lhames@gmail.com</a>> wrote:<br>
> Hi Sanjoy,<br>
><br>
>> You need the hijack-return-pc approach *in addition* to a call-site<br>
>> patching approach.  Modifying the return PC lets you guarantee that<br>
>> nothing will *return* into the old generated code. To guarantee that<br>
>> nothing will *call* into it either you could use a double indirection<br>
>> (all calls go through a trampoline) or patchpoints.<br>
><br>
> You need to hijack the return addresses if you want to delete the original<br>
> function body immediately, but what if you just leave the original in-place<br>
> until you return through it? That is the scheme that Pete and I had been<br>
> talking about. On the one-hand that means that the old code may live for an<br>
> arbitrarily long time, on the other hand it saves you from implementing some<br>
> complicated infrastructure. I suspect that in most JIT use-cases the cost of<br>
> keeping the duplicate function around will be minimal, but I don't actually<br>
> have any data to back that up. :)<br>
<br>
</span>I agree that the cost of keeping around the old generated code is<br>
likely to be small.<br>
<br>
However, you may need to ensure that nothing returns into the original<br>
code for correctness:  the reason you're replacing an old compilation<br>
with a new one could very well be that you want to do something that<br>
makes the old piece of code incorrect to execute.  For instance, in<br>
the old compilation you may have assumed that class X does not have<br>
any subclasses (and you devirtualized some methods based on this<br>
assumption), but now you're about to dlopen a shared object that will<br>
introduce a class subclassing from X.  Your devirtualization decisions<br>
will be invalid after you've run dlopen, and it would no longer be<br>
correct to execute the old bit of code.<br>
<br>
You could also do this by appending all calls / invokes with<br>
<br>
  some_other_method();<br>
  if (!this_method->is_still_valid) {<br>
    do_on_stack_replacement(); // noreturn<br>
    unreachable;<br>
  }<br>
  // continue normal execution<br>
<br>
and that's perfectly sound because you'll always check validity before<br>
re-entry into a stack frame.  Is this what you meant by frame<br>
residence counting?<br>
<span class=""><br>
> It's worth noting that, as per its design goals, Orc is agnostic about all<br>
> this. Either scheme, or both, should be able to be implemented in the new<br>
> framework. It's just that nobody has implemented it yet.<br>
<br>
</span>So this is the Patches Welcome(TM) part. :P<br>
<span class=""><font color="#888888"><br>
-- Sanjoy<br>
</font></span></blockquote></div><br></div></div></div>