[Mono-dev] Patch: Fast virtual generic method calls

Rodrigo Kumpera kumpera at gmail.com
Thu Sep 25 22:21:53 EDT 2008


Hey Mark,

2008/9/25 Mark Probst <mark.probst at gmail.com>

> Hey everybody,
>
> This is my second attempt at implementing fast virtual generic method
> calls.  The implementation is very close to Paolo's proposal here:
>
>  https://bugzilla.novell.com/show_bug.cgi?id=324481
>
> The main difference is that I don't hash the methods into slots but use
> the (until now unused) "normal" vtable slots for the thunks.  This is
> necessary because with generic code sharing the method signature is not
> known statically.
>

Makes sense, the space is already these. Does it handle dispatching of
interface generic methods? The code in method-to-ir.c suggests not.



>
> A big problem with this implementation is the memory management of the
> thunks.  Since thunks become obsolete when new method instantiations are
> added we have to reclaim their memory.  We can only do this safely if we
> know that no thread is still executing the thunk code.  The current
> solution is a hack: Freed thunks are queued until there are 50 of them,
> at which point for each new freed thunk we reclaim the oldest one in the
> queue.  The other problem with this approach is that if there are only a
> few thunks which grow and grow we won't be able to reuse the freed small
> pieces, i.e. a program can easily make us use an arbitrary amount of
> memory by having a single virtual generic method which is instantiated
> with a large number of different type arguments (easy to do
> recursively).
>
> One solution I have to the latter issue is by splitting the thunks into
> small fixed-size code pieces, in the simplest case one piece per
> decision-tree node.  Not difficult to implement.  Another solution would
> be to have a code manager which permits freeing items :-)
>
> The patch currently only supports x86.
>


Since you have a hashtable with the expansions, what about introducing a
limit
on the number of trunks per method, this change should not be hard.

Have you thought about using something else than a MonoMethod as key? We
could,
for example, use the following scheme:

Right now it's only possible to share if all instantiations are reference
types. I guess we
can determine if the method is shareable on first compilation, which is
before any trunk code
is generated.

Given that we know this, we could store in the upper bit of the tokens used
for resolving the trunk
if they refer to a sharable instantiation. Then on trunk code, if the method
is sharable
we check this bit and avoid generating tons of trunks.

But even with that we would still need to generate trunks. If we generate
then partially, as you suggest,
for each decision node, I can't think how the current scheme would allow for
making it balanced.

I guess it would be doable if we stored the keys in an array not part of the
code, as sorting it would not
mean doing a lot of code modification, so no icache flushes unless we wanted
to link a new trunk block
in the tree and each trunk block could be a 15 entries decision tree.


Cheers,
Rodrigo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080925/11e497dd/attachment.html 


More information about the Mono-devel-list mailing list