[Mono-devel-list] VTable & Interfaces

Willibald Krenn Willibald.Krenn at gmx.at
Tue Mar 1 10:50:59 EST 2005


Ben Maurer schrieb:
> The answer is `yes, you have to, but it doesn't cost nearly as much as
> you think it does'

> It wouldn't be too hard to set a little hack where each class has two
> extra fields:
> 
> MonoClass* first_child
> MonoClass* next_sibling
> 
> This would allow us to easily just look at the people who derived.

Yes, that would be possible. Additionally some way of narrowing down the 
search in the interface part of the VMTs would be nice. I have to think 
about this.

> Also, why do you need to patch the actual vtable? Isn't the address to
> the method going to be embeded in quite a few places anyways?

Well, this won't work with recompilable methods anymore: It's 
potentially unsafe to overwrite the first XX bytes of an active method, 
because there could be code like
  0:push bp
   :..
l1:..
   :call <another method>
   :..
XX:..
   :call <another method>
   :jnz  <l1>

So before a method can be patched with a stub that calls a service 
routine that patches the caller code, we have to do a stack walk of each 
running thread and if the to-be-replaced method is found in the walk, we 
have to cancel the replacement and try again at a later time. 
(Potentially never being able to replace the method because of loops or 
high call frequency ..)

The cleaner solution is to always do indirect calls and simply exchange 
the pointer in the table upon method replacement: No code patching 
necessary and the stack walks are only necessary if we want to free the 
old method.. (But not in case we want to patch the code.)
Due to branch prediction I don't think the penalty for doing indirect 
calls is too high. (Especially as the pointer table page will 99% be in 
cache..)

Additionally the magic tramp call (and thus the lmf/regsave code) is 
only executed once for a new method - all other calls go directly to the 
newly compiled method and not over the magic tramp as now.

BTW: With this model it's still possible to embed the address in the 
caller if we find recompilation is not worth the effort. (This is 
because the indirect call is about 8 bytes (AMD64) and the direct one is 
5 bytes..)

This still leaves virtual methods out of the equation: Basically each 
virtual method has an entry in the VMTs of different classes. As we 
won't install patch code, we have to replace all these pointer 
occurrencies if we want to replace a virtual method.
(Alternatively we could introduce another indirection in the sense that 
the VMT entries are pointers to locations where the real address of the 
method is saved. However, this would mean an additional mov (with memory 
access) in case of a virtual method call and therefore I think this is a 
bad idea. To preserve runtime performance it's better to look up all VMTs..)


So I'll do the indirect calls this week - I then hope that the framework 
is ready after this work is done!

Willi




More information about the Mono-devel-list mailing list