MSDN > 論壇首頁 > Building Development and Diagnostic Tools for .Net > Profiling methods in generic type
發問發問
 

已答覆Profiling methods in generic type

  • Wednesday, 1 July, 2009 17:58Yitao 使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     
    Hi,

      I recently discovered a bug in my IL-rewriting profiler.  A method in a generic type is being re-JITted given different generic parameters.  For example, the methods MyType<int>.Foobar() and MyType<string>.Foobar() will each be JITted once with unique FunctionIDs but identical mdTokens.  Let's say my simplified profiler code looks like

    HRESULT
    ProfilerCallback::JITCompilationStarted(FunctionID functionID, BOOL isSafeToBlock)
    {
        ModuleID moduleID;
        mdToken token;
        LPBYTE original;
        ULONG sz;
        LPBYTE updated;
    
        fProfilerInfo->getFunctionInfo(functionID, NULL, &moduleID, &token);
        fProfilerInfo->GetILFunctionBody(moduleID, token, (LPCBYTE*)&original, (ULONG*)&sz);
    
        // ... insert IL equivalent of Console.WriteLine("Hello World");  ...
    
        fProfilerInfo->SetILFunctionBody(moduleID, token, updated);
        return S_OK;
    }

    My questions are

      1.  In the case where MyType<int>.Foobar() and MyType<string>.Foobar() are called, this code would cause MyType<string>.Foobar() to be instrumented twice.  When I invoke MyType<string>.Foobar(), "Hello World" would be printed twice.  To the callback JITCompilationStarted, modifying IL for (identical) method token fetched from the two (unique) function ID does not make sense, so why is it being JIT-ted multiple times?
      2.  Did re-JIT just work???  Or was this a lucky accident?

    Yitao

解答

  • Thursday, 2 July, 2009 16:42David BromanMSFT, 擁有者使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆

    Hi, Yitao.  With generics, you'll see a single methodDef in metadata for the function's definition (MyType<T>.Foobar()), but multiple FunctionIDs for different instantiations.  Generally, for each instantiation using a value type you'll see a different FunctionID, and all instantiations using a reference type share a FunctionID.

    Since generics instantiate into multiple FunctionIDs, you see separate JIT notifications for them.  As you discovered, you must be careful with your instrumentation when you see the second, third, etc., JIT for the same methodDef.  You need to scan through the IL the CLR gives you, and not re-instrument it, if it's already instrumented.  (Often you can tell, as your instrumentation probably does something rather unique that you can search for.)


    Thanks,
    Dave

所有回覆

  • Thursday, 2 July, 2009 16:42David BromanMSFT, 擁有者使用者勳章使用者勳章使用者勳章使用者勳章使用者勳章
     已答覆

    Hi, Yitao.  With generics, you'll see a single methodDef in metadata for the function's definition (MyType<T>.Foobar()), but multiple FunctionIDs for different instantiations.  Generally, for each instantiation using a value type you'll see a different FunctionID, and all instantiations using a reference type share a FunctionID.

    Since generics instantiate into multiple FunctionIDs, you see separate JIT notifications for them.  As you discovered, you must be careful with your instrumentation when you see the second, third, etc., JIT for the same methodDef.  You need to scan through the IL the CLR gives you, and not re-instrument it, if it's already instrumented.  (Often you can tell, as your instrumentation probably does something rather unique that you can search for.)


    Thanks,
    Dave