How do are callers patched when a method is recompiled?

Tom Rodriguez Thomas.Rodriguez at Sun.COM
Mon Oct 6 13:58:06 PDT 2008


The basic machinery relies on making methods not entrant and  
reclaiming them once we're sure no inline cache could still contain a  
reference to them.  We overwrite the first instructions of the  
generated code with an instruction sequence that gets us into the  
handle_wrong_method stub.  Look at NativeJump::patch_verified_entry  
and SharedRuntime::handle_wrong_method.  This forces any callers to  
reresolve the call site and either find any new generated code or fall  
back to the interpreter.  NMethodSweeper takes care of cleaning all  
the inline caches that might still contain references to the nmethod  
by cleaning a portion of the code cache at every safepoint.  Once  
we're sure that no inline cache could contain a reference to the not  
entrant nmethod we mark it for reclamation.  There are some tricky  
bits in the runtime where code is operating on an nmethod and we want  
to be sure it isn't swept from underneath us and these use the  
nmethodLocker which is basically a reference counter that delays the  
freeing of the nmethod.

We're not attempting to be aggressive in how quickly we reclaim the  
storage from the code cache and there are some problems with the  
current code if the rate of invalidation gets too high but those are  
just implementation details.  There are a lot of ways our current  
implementation could be improved but it performs adequately in most  
ways so other than a few bug fixes it largely hasn't changed for a  
long time.  The main flaw we'll have to address in the future is that  
if the rate of invalidation and/or the number of nmethods is high it  
performs way too much work at each safepoint.  It processes a 1/4 of  
the code cache each time and it probably needs metric that is tied how  
much work it performs instead.

tom

On Oct 5, 2008, at 1:36 PM, Yale Zhang wrote:

> Hi. I'm trying to build a dynamic optimization framework for LLVM  
> and have been looking at HotSpot for ideas on how to patch the  
> callers when a method is recompiled. I've spent over an hour looking  
> at functions like new_nmethod, register_method and I can't figure it  
> out.
>
> I've been thinking about the following approaches:
>
> 1. lazy relinking - keep the old code and patch callers only when  
> they refer to the old code. I guess you can do this by patching the  
> old code to find the call site and patch it. Then there's the  
> question of
> when to throw away the old fragment. Could use reference counting or  
> garbage collection.
>
> 2. relink immediately - upon recompiling, all callers are patched.  
> This would be expensive because it would entail either going through  
> every function looking for such a call (more processing) or  
> maintaining a list of callers for each function (more storage).
>
> So, how does HotSpot do it?




More information about the hotspot-dev mailing list