Profiling methods in generic type
- 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
解答
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- 已標示為解答Zhi-Xin YeMSFT, 版主2009年7月8日 下午 01:39
所有回覆
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- 已標示為解答Zhi-Xin YeMSFT, 版主2009年7月8日 下午 01:39

