# Monday, 11 July 2011
« java.lang.AutoCloseable | Main | New Development Snapshot »
How to Detect if a Method is Overridden Redux

Using a clever hack is always risky. Previously I described how to use the ldftn and ldvirtftn CIL instructions to detect if a method is overriden by a subclass. It turns out that there is a problem with this trick. If the method containing the ldftn instruction is JITted before the method it refers to, the method pointer returned (and burned into the generated code) is the JIT stub, when the method subsequently is JITted the new function pointer is stored in the vtable of subsequently loaded subclasses and the detection method yields a false positive.

Here's a small C# demo that demonstrates an equivalent effect:

using System;
using System.Runtime.CompilerServices;

class Program {
  static void Main() {
    RuntimeMethodHandle m = typeof(Program).GetMethod("Foo").MethodHandle;
    //RuntimeHelpers.PrepareMethod(m);
    Console.WriteLine(m.GetFunctionPointer());
    new Program().Foo();
    Console.WriteLine(m.GetFunctionPointer());
  }

  public virtual void Foo() { }
}

When you run this program on .NET, it prints out two different values. One possible solution is present in the commented out line, if you uncomment that the two pointer values printed will be the same, because PrepareMethod forces the method to be JIT compiled.

Another slightly more robust method is to avoid ldftn and use ldvirtftn to get the base method as well. The downside is that you need to have an instance of an object of a class that does not override the method in question.

Finally, if you want to use this approach consider using this as an optimization and if this detection is positive, use reflection to confirm.

Monday, 11 July 2011 16:35:52 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
Name
E-mail
Home page

I apologize for the lameness of this, but the comment spam was driving me nuts. In order to be able to post a comment, you need to answer a simple question. Hopefully this question is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.

Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)

Answer:  
Comment (HTML not allowed)  

Live Comment Preview