# Sunday, 01 June 2008
« Introducing CallerID Part 1 | Main | Introducing CallerID Part 3 »
Introducing CallerID Part 2

In part 1 we saw the Java source for the ForName benchmark, now let's look at some C# code that is roughly equivalent to what IKVM generates from the Java version:

class ForName  {
  private static readonly __CallerID __callerID = new __CallerID();
  private sealed class __CallerID : ikvm.@internal.CallerID { }

  public static void Main(string[] args) {
    java.lang.Class.forName("java.lang.Object", __callerID);
    long start = java.lang.System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
      java.lang.Class.forName("java.lang.Object", __callerID);
    long end = java.lang.System.currentTimeMillis();
    java.lang.System.@out.println(end - start);
  }
}

This shows that the compiler passes an extra parameter to the Class.forName() method that carries the identity of the caller's class.

The source for ikvm.internal.CallerID is available in cvs. The class is public and has a protected constructor but has no public methods (they are all internal to the IKVM.OpenJDK.ClassLibrary assembly). The intended usage is shown above, you should extend it with a private class that is nested inside the class whose identity you want to pass to a CallerID requiring API.

The example also demonstrates how you can call these methods from C# if you want to get the best performance, however I recommend using the standard versions of the APIs unless the performance difference is critical to your application.

Above we looked at the caller, now let's look at the callee. Here's the Java source for the Class.forName() method:

@ikvm.internal.HasCallerID
public static Class forName(String className)
            throws ClassNotFoundException {
  return forName0(className, true, ClassLoader.getCallerClassLoader());
}

I added the HasCallerID annotation to signal to ikvmc that it should add the implicit CallerID parameter and ClassLoader.getCallerClassLoader() has been turned into an intrinsic that calls getCallerClassLoader() on the passed in CallerID object instead. Here's the C# equivalent that ikvmc produces for the Class.forName() method:

public static java.lang.Class forName(string className, ikvm.@internal.CallerID callerID) {
  return java.lang.Class.forName0(className, truee, callerID.getCallerClassLoader());
}

[IKVM.Attributes.HideFromJava]
public static java.lang.Class forName(string className) {
  System.Diagnostics.StackFrame caller = new System.Diagnostics.StackFrame(1, false);
  return forName(className, ikvm.@internal.CallerID.create(caller));
}

In part 3 we'll look at the design decisions behind this implementation.

Sunday, 01 June 2008 10:15:18 (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