关于C#静态函数什么时候被调用的问题
2010-09-30 21:00:31 来源:WEB开发网上面关于B 的静态构造函数生成的汇编代码已经解释完毕了,现在的问题是,我们是怎样到达这里的?那当然是看堆栈啦,由于堆栈的调用次序和显示的顺序刚好相反,所以下面的注释序号是反向的:
0:000> kp
ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
#
# 5. 调用刚刚即时编译好了的 类型B的静态构造函数
#
0020d0b8 79366025 0x4e4fe6a
#
# 4. CallDescrWorker应该是 JIT编译器在托管程序执行过程当中,介入编译尚未被JIT的函数的入口
# 然而遗憾的是,这几个函数,以及JIT如何介入的机制我还是不是特别熟悉,所以……呃……
# 你知道的……就这么着吧
#
0020d0c8 7937d2c2 mscorwks!CallDescrWorkerInternal+0x33
0020d4f4 7937d1b7 mscorwks!CallDescrWorker(void * pSrcEnd = 0x0020d670, unsigned int numStackSlots = 0, struct ArgumentRegisters * pArgumentRegisters = 0x0020d640, unsigned int fpRetSize = 0, void * pTarget = 0x003c31d0)+0xd2 [c:\sscli20\clr\src\vm\class.cpp @ 11285]
0020d620 794a76c1 mscorwks!CallDescrWorkerWithHandler(void * pSrcEnd = 0x0020d670, unsigned int numStackSlots = 0, struct ArgumentRegisters * pArgumentRegisters = 0x0020d640, unsigned int fpReturnSize = 0, void * pTarget = 0x003c31d0, int fCriticalCall = 0)+0x187 [c:\sscli20\clr\src\vm\class.cpp @ 11198]
#
# 3. 找到类型B的静态构造函数对应的MethodDesc,调用这个函数
#
0020d7d8 794a6fa6 mscorwks!MethodDesc::CallDescr(unsigned char * pTarget = 0x003c31d0 "???", class MetaSig * pMetaSigOrig = 0x0020d850, unsigned int64 * pArguments = 0x00000000, int fIsStatic = 1, int fCriticalCall = 0, int fPermitValueTypes = 0)+0x711 [c:\sscli20\clr\src\vm\method.cpp @ 1883]
0020d800 792f8104 mscorwks!MethodDesc::CallTargetWorker(unsigned char * pTarget = 0x003c31d0 "???", class MetaSig * pMetaSig = 0x0020d850, unsigned int64 * pArguments = 0x00000000, int fCriticalCall = 0, int fPermitValueTypes = 0)+0x46 [c:\sscli20\clr\src\vm\method.cpp @ 1572]
0020d820 79321a25 mscorwks!MethodDescCallSite::CallTargetWorker(unsigned int64 * pArguments = 0x00000000, int fPermitValueTypes = 0)+0x34 [c:\sscli20\clr\src\vm\method.hpp @ 1804]
0020d834 7949522d mscorwks!MethodDescCallSite::Call(unsigned int64 * pArguments = 0x00000000)+0x15 [c:\sscli20\clr\src\vm\method.hpp @ 1910]
#
# 2. 在类型B的方法表里面,找到它的静态构造函数,并且执行它。
#
0020d8d0 79494e1b mscorwks!MethodTable::RunClassInitWorker(class MethodDesc * pInitMethod = 0x003c3080, class OBJECTREF * pThrowable = 0x0020e054)+0xbd [c:\sscli20\clr\src\vm\methodtable.cpp @ 2692]
0020dab8 794955de mscorwks!MethodTable::RunClassInitEx(class OBJECTREF * pThrowable = 0x0020e054)+0x28b [c:\sscli20\clr\src\vm\methodtable.cpp @ 2657]
0020e4e8 79493859 mscorwks!MethodTable::DoRunClassInitThrowing(void)+0x38e [c:\sscli20\clr\src\vm\methodtable.cpp @ 2840]
0020e4fc 7955143f mscorwks!MethodTable::CheckRunClassInitThrowing(void)+0xa9 [c:\sscli20\clr\src\vm\methodtable.cpp @ 1902]
0020e5dc 79550d3e mscorwks!MethodDesc::DoPrestub(class MethodTable * pDispatchingMT = 0x00000000)+0x3ff [c:\sscli20\clr\src\vm\prestub.cpp @ 908]
#
# 1. 在前面的Main函数执行过程中,中途碰到需要即时编译类型B的静态构造函
# 数的要求,中断正常的托管程序执行顺序。由JIT 编译器跳入执行即时编译过
# 程。
#
0020e6ec 0051f3e2 mscorwks!PreStubWorker(class PrestubMethodFrame * pPFrame = 0x0020e71c)+0x2de [c:\sscli20\clr\src\vm\prestub.cpp @ 662]
0020e748 79366025 0x51f3e2
0020e750 793660a4 mscorwks!CallDescrWorkerInternal+0x33
0020e76c 003c2e70 mscorwks!GetThreadGeneric+0x18
00000000 00000000 0x3c2e70
更多精彩
赞助商链接