How do are callers patched when a method is recompiled?
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.
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
> 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