locked
Are ModuleID, AssemblyID, ClassID or FunctionID invariant?

    Question

  • I am working on a CLR profiler and I have certain methods that I instrument.  JITCompilationStarted gives me a functionID and I can do:
    FunctionID -> GetFunctionInfo -> ModuleID -> GetModuleInfo -> AssemblyID -> GetAssemblyInfo -> AssemblyName.

    That gets me the assembly name.  I can then get the method name by doing:
    FunctionID -> GetTokenAndMetaDataFromFunction -> IMetaDataImport -> GetMethodProps -> MethodName

    And finally to get the class name I can do:
    IMetaDataImport -> ClassName

    Once I have the Assembly, Class and Method name I can determine whether or not to instrument a particular method by doing string comparisons on each.  However, I start out with a FunctionID and within 1 method call (GetFunctionInfo) I have ClassID and ModuleID and with a second call I have AssemblyID.  If any of these are invariant it would save me a number of method calls as well as the string comparisons.  Also, if just the FunctionID was invariant within a given class I could do an integer comparison and give up early if it didn't match the method I want to instrument, even if I still had to do all the work listed above to ensure it wasn't the same method from a different class.

    Monday, December 03, 2012 5:36 PM

Answers

  • Hi, Micah.

    Thanks for the clarification.  You'll definitely want to do some kind of string comparison to harden your tool against updates to the Fx assemblies that are outside your control.  But you might be able to find ways to minimize the string comparisons.  For example, as a module you care about loads, you could do all your method string lookups at that point to determine the mdMethodDef metadata tokens you care about (converting string names you care about to metadata tokens in bulk for that module), and then at JIT time just compare metadata tokens.

    Thanks,
    Dave

    Wednesday, December 05, 2012 1:09 AM
    Owner

All replies

  • Hi, Micah, could you define "invariant"?

    Note that ALL profiler-defined IDs change from run-to-run (they're just pointers), if that's what you're talking about.  Metadata tokens are more consistent, but they could change on each compilation.

    Please see http://blogs.msdn.com/b/davbr/archive/2011/10/17/metadata-tokens-run-time-ids-and-type-loading.aspx for details.

    Thanks,
    Dave

    Tuesday, December 04, 2012 10:06 PM
    Owner
  • I actually found that article while looking for something else after posting my question here and it more or less answers it.  In particular, I want to be able to quickly identify whether a particular function is of interest to me without having to make too many API calls due to the costs and the fact that we are writing a production profiler.

    The functions we instrument are mostly part of the .NET Framework and since there are a limited number of framework versions it sounds like we may be able to do quick checks as long as we get the tokens for every Framework version?

    For example, if I want to instrument System.Web.HttpContext.ctor I currently have to make a large number of API calls when JITCompilationStarted is called just to find out if the function about to be JIT compiled is System.Web.HttpContext.ctor.  In a perfect world, JITCompilationStarted would give me a GUID that I could compare against one that I found in advance and be done.  It sounds like what I need is to find the MethodToken for each version of the .NET Framework in advance and then turn the FunctionID into a MethodToken and compare against the one for the Framework that is loaded.

    For methods that we *do* instrument, the overhead costs don't matter to much.  It is the other 99% that we would like to exit early on so we don't waste time doing a bunch of string compares only to find out if we don't need to be instrumenting the function that is about to be JIT compiled.

    Wednesday, December 05, 2012 1:02 AM
  • Hi, Micah.

    Thanks for the clarification.  You'll definitely want to do some kind of string comparison to harden your tool against updates to the Fx assemblies that are outside your control.  But you might be able to find ways to minimize the string comparisons.  For example, as a module you care about loads, you could do all your method string lookups at that point to determine the mdMethodDef metadata tokens you care about (converting string names you care about to metadata tokens in bulk for that module), and then at JIT time just compare metadata tokens.

    Thanks,
    Dave

    Wednesday, December 05, 2012 1:09 AM
    Owner
  • If you are only interested in a small number of methods, is there any reason you cannot find and cache the relevant MethodDef tokens (along with the ModuleID) in the ModuleLoadFinished callback for use in your JITCompilationStarted callback?
    Saturday, December 15, 2012 2:39 AM