[Mono-devel-list] RAPGO Proposal
Willibald.Krenn at gmx.at
Mon Nov 29 08:07:10 EST 2004
Paolo Molaro schrieb:
> Zoltan has already some code that does this, though I don't remember
> if it's finished cleaned up. Look in aot.c.
Ok, I'll do. But this isn't my number 1 priority..
>> I've come up with following 'idea': Each method is called
>> indirectly via call *rax (where rax points to some GOT). So by
>> changing the offset every call will go to the new location.
>> Another technique would be to replace the existing method by
>> some code that patches the caller's address to jump to the new
>> code the next time directly. This however means that we would
>> have to take care how long a given 'Patcher' needs to be
>> preserved... (some problem GC could take care of..)
> We have already the code to deal with this.
Could you give me a pointer? I wasn't aware of that - must be some
relatively new thing..
>> Before freeing/overwriting a method we also have to ensure no
>> thread is executing this piece of code anymore. Simple
>> Entry/Exit counters should be able to handle that..
> Counters are not needed and would be too slow. We can simply walk
> the stack of the various threads and see if any is inside the method.
> At first, there is no need to free the code, since we'll only recompile a
> method once or twice, so the 'leak' is bounded.
I see. So you are first patching all invocations to go to the new method
and will then check all threads whether they are within the 'old' method..
When do you think stack walking will be slower than having counters?
>> (In case of an endless loop, code could be patched so that this
>> thread generates a signal..)
> One of the issues is how to handle methods that are never exited. If a method
> is called many times it's easy to recompile it and make the code call the new
> faster version. However, if most of the time is spent inside a single method
> which is executed once, for example, just recompiling and changing the call
> sites is not going to work. We'd need to transfer the state from the old
> stack/registers to the state as needed by the new code: this is far from
> trivial and one of the reasons I prefer statistical profiling vs
> counter-based profiling with code embedded in the slow method compilation
> (though I guess in such cases that code could be overwritten with nops).
> With statistical profiling the code is at least not slowed down by
> the profiling overhead.
Well, a sampling profiler will slow down execution too, but not that
much. However, you won't get all information you need for certain
optimizations by using a sampling profiler AFAIK, so IMO it's still
beneficial to instrument methods that have been shown by sampling to be
'hot'. The resulting slowdown will IMO be minimal (especially if MMX
registers are used, the float pipeline isn't populated by the method to
be profiled and results get written to memory once) and therefore
Code that runs endlessly in a loop probably isn't a good candidate for
runtime replacement at all. Probably 'transfer-points' - icalls p/i
calls are good candidates - could be introduced that have a known
stack/register state, but well..
However, mono could memorize methods that run some endless loop for the
next time the application is run.
>> Currently every code that is being emitted gets copied to it's
>> final location - smells like overhead to me..
>> What about mmap and direct emit into this area?
>> This would also save time for freeing/allocating memory for
>> replacement code.
> I don't think any of this is an issue: a memcpy of the code is going
> to be a very tiny fraction of the time spent compiling. And I don't see
> any relation with the freeing/allocating.
Ok, point taken. (Although if you'd move inssel into the backend and let
the inssel generate the final code into the target buffer, things should
be faster. However, it's questionable how much.)
I'm quite surprised no-one commented on my C++ proposal! So does that
mean if I send patches that use C++, you'll accept them?
More information about the Mono-devel-list