Suppose you want to know if (the class of) a particular object overrides a virtual method. For an example of this see OpenJDK's Thread.isCCLOverriden() (line 1573).
In Java the obvious way to do this would be to use reflection. On the CLR there is another way that is both more accurate1 and more efficient.
Here's the MSIL method from IKVM's java.lang.Thread.isCCLOverridden() implementation:
.method private hidebysig static bool isCCLOverridden(class java.lang.Thread A_0) cil managed
{
ldftn instance class java.lang.ClassLoader java.lang.Thread::getContextClassLoader()
ldarg.0
ldvirtftn instance class java.lang.ClassLoader java.lang.Thread::getContextClassLoader()
ceq
ldftn instance void java.lang.Thread::setContextClassLoader(class java.lang.ClassLoader)
ldarg.0
ldvirtftn instance void java.lang.Thread::setContextClassLoader(class java.lang.ClassLoader)
ceq
and
ldc.i4.0
ceq
ret
}
Instead of running a zillion instructions and accessing a lot of cold data for reflection, this simply leverages the information the JIT already has about virtual methods.
Here's the x86 code this turns into:
push ebp
mov ebp,esp
push esi
push ebx
mov esi,ecx
push 258F58h
mov ecx,esi
mov edx,259240h
call JIT_VirtualFunctionPointer
mov edx,25DCA0h
cmp eax,edx
sete bl
movzx ebx,bl
push 2591A0h
mov ecx,esi
mov edx,259240h
call JIT_VirtualFunctionPointer
mov edx,25DCB0h
cmp eax,edx
sete al
Read more: IKVM.NET Weblog
In Java the obvious way to do this would be to use reflection. On the CLR there is another way that is both more accurate1 and more efficient.
Here's the MSIL method from IKVM's java.lang.Thread.isCCLOverridden() implementation:
.method private hidebysig static bool isCCLOverridden(class java.lang.Thread A_0) cil managed
{
ldftn instance class java.lang.ClassLoader java.lang.Thread::getContextClassLoader()
ldarg.0
ldvirtftn instance class java.lang.ClassLoader java.lang.Thread::getContextClassLoader()
ceq
ldftn instance void java.lang.Thread::setContextClassLoader(class java.lang.ClassLoader)
ldarg.0
ldvirtftn instance void java.lang.Thread::setContextClassLoader(class java.lang.ClassLoader)
ceq
and
ldc.i4.0
ceq
ret
}
Instead of running a zillion instructions and accessing a lot of cold data for reflection, this simply leverages the information the JIT already has about virtual methods.
Here's the x86 code this turns into:
push ebp
mov ebp,esp
push esi
push ebx
mov esi,ecx
push 258F58h
mov ecx,esi
mov edx,259240h
call JIT_VirtualFunctionPointer
mov edx,25DCA0h
cmp eax,edx
sete bl
movzx ebx,bl
push 2591A0h
mov ecx,esi
mov edx,259240h
call JIT_VirtualFunctionPointer
mov edx,25DCB0h
cmp eax,edx
sete al
Read more: IKVM.NET Weblog