On Mar 11, 2013, at 8:47 PM, Nigel Delaney <nigel.dela...@outlook.com> wrote:
> However, I was surprised to learn when disassembling code that both Mono and 
> Microsoft seem to ignore this optimization, and emit all method calls as 
> callvirt instructions in IL regardless of whether or not they are actually 
> virtual method calls, which seems to defeat the whole point of not being java.

No. That's a different optimization. ;-)

A callvirt to a non-virtual method does not bind the method virtually; it binds 
it non-virtually, and the method cannot be overridden.

So why use callvirt? Because callvirt implicitly checks the target's `this` 
reference and will throw a NullReferenceException when it's null.

It is thus a space optimization: instead of needing to null-check arguments 
everywhere, they just rely on callvirt to do the null check.

> A Microsoft employee blogged about this  
> (http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx)
>   and it seems that made this change to ensure that instance methods could 
> not be called on null instance references (a debatable decision perhaps). 

I should finish reading emails before replying.

> I gather/suspect that Microsoft still optimizes the callvirt instruction 
> during the JIT stage to call the method and check for a null reference,

This is not possible. At JIT time, they just have data, they just have 
instructions to execute. They don't have everything that won't be known until 
runtime. It's thus ~impossible (in the general case) to know if a given 
instance will be null at JIT time. You will know if the instance is null at 
runtime.

For example, consider string.Concat(). That method will be invoked from lots of 
different places in your code. It _cannot_ null check the arguments at JIT 
time, because there's only one (~random) code path that will hit it at JIT 
time, but it'll be invoke at runtime by lots of different places.

The null check thus must be at runtime.

> And if Mono also is able to optimize callvirt calls that are not actually 
> virtual calls?

Yes. callvirts to non-virtual calls do not go through the virtual method table, 
they just directly call the target method after the null check.

 - Jon

_______________________________________________
Mono-list maillist  -  Mono-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to