Mostly Software

June 2, 2008

Sharing Generic Methods

Filed under: Software — Tags: , , — schani @ 7:12 pm

All of my posts on sharing generic code so far have been about sharing non-generic methods of generic classes, like this one:

class Gen<T> {
  public T [] newArr (int n) {
    return new T [n];
  }
}

But what about generic methods, like this one:

class Gen<S> {
  public Dictionary<S,T> newDict<T> () {
    return new Dictionary<S,T> ();
  }
}

If we want to share this methods between different instantiations, i.e. different type values of T, we need to provide a place for the code to look up the type of Dictionary<S,T>. This place cannot be the runtime generic context, because the data in there only depends on the type arguments of the class, i.e. S, but not of generic methods.

Our solution is to introduce a data structure very similar to the runtime generic context, called the method runtime generic context, or MRGCTX. It is associated not with generic classes and their type arguments, like the RGCTX, but with generic methods and their type arguments. We use the same MRGCTX for generic methods of a specific class if the method type arguments are the same. As an example, these methods would all share the same MRGCTX:

Gen<object>.foo<object,string> ()
Gen<object>.bar<object,string> ()
Gen<object>.quux<object,string> ()

while no two of these methods would use the same MRGCTX:

Gen<object>.foo<object,string> ()
Gen<object>.foo<string,object> ()
Gen<string>.foo<string,object> ()
Ban<string>.foo<string,object> ()

The MRGCTX contains, apart from the RGCTX-like slots, two items of data: A pointer to the vtable of the method’s class, and the values of the method’s type arguments. The first one is needed to get to the class’s RGCTX if no this argument is passed, i.e. in static generic methods. The type arguments are needed to instantiate new slots in the MRGCTX – without knowing what the value of T is, for example, we cannot look up the type Dictionary<S,T>.

So how much memory do we save with shared generic methods? In my previous post on sharing generic code I presented a table with the savings in memory my three large test applications. Here it is again, updated with data for sharing generic methods:


No sharing Sharing Sharing w/gen methods
Methods
compiled
Code
produced
Methods
compiled
Code
produced
Methods
compiled
Code
produced
Memory for
(M)RGCTXs
Savings
IronPython 3614 719k 3368 691k 3324 687k 7k 25k
Nemerle 7210 2001k 6302 1943k 6150 1891k 34k 76k
F# 15529 2193k 11431 2062k 9823 1652k 154k 387k

Note that this time I’m also counting all the memory used by (M)RGCTXs and the (M)RGCTX templates, which I didn’t do last time.

About these ads

2 Comments

  1. This is fascinating. I wish I knew more about generics and how they are compiled. I will have to read more of your blog :)

    Comment by Sam — June 5, 2008 @ 11:52 pm

  2. [...] Filed under: Software — by schani @ 7:37 pm Tags: generics, mono, types Since my last report on generic code sharing I chased down a few bugs we uncovered when trying out IronPython 2.0. That [...]

    Pingback by Another Generic Sharing Update « Juggling, Photography, Software, and Atheism — June 27, 2008 @ 7:37 pm


RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: