.Net 7 内存模型函数描述结构MethoDesc

楔子

讲一些CLR里面的内存模型。本篇MethodDesc,意为函数的描述之意,看下一个函数在CLR里面是如何被描述的。

MethodDesc结构

这个结构体在CLR里面高达1600多行,这里仅截取一些

class MethodDesc {     friend class EEClass;     friend class MethodTableBuilder;     friend class ArrayClass;     friend class NDirect;     friend class MethodDescChunk;     friend class InstantiatedMethodDesc;     friend class MethodImpl;     friend class CheckAsmOffsets;     friend class ClrDataAccess;     friend class MethodDescCallSite;  #ifdef _DEBUG     LPCUTF8         m_pszDebugMethodName;     LPCUTF8         m_pszDebugClassName;     LPCUTF8         m_pszDebugMethodSignature;     PTR_MethodTable m_pDebugMethodTable; #endif      PTR_GCCoverageInfo m_GcCover;     UINT16      m_wFlags3AndTokenRemainder;     BYTE        m_chunkIndex;     BYTE        m_bFlags2;     WORD m_wSlotNumber;     WORD m_wFlags; }; 

这里面可以看到它除了友元类之外,还有一些调试以及非调试的时候所包含的字段。

代码

看下这个简单的例子,在MethodDesc字段里面的表示

    internal class Program     {         static void Main(string[] args)         {             Console.WriteLine("Hello, World!");             Console::ReadLine()         }     } 

字段

如上例子所示,Program类,以及Main函数在MethodDesc里面的表示如下

一:

m_pszDebugMethodName = 0x00007ffa973f7dd8 "Main" 

0x00007ffa973f7dd8这个地址指向了入口函数Main函数字符串值。

二:

m_pszDebugClassName = 0x00007ffa9739fef0 "ConsoleApp2.Program" 

同样是指向字符串

三:

m_pszDebugMethodSignature = 0x00007ffa973f7e28 "void *(string[])" 

四:

m_pDebugMethodTable = 0x00007ffa9739ff28 {[Type Name]= "ConsoleApp2.Program" } 

可以看到,在IfDebug模式下,类名,函数名,函数的返回值以及参数,以及类的MethodTable都包含在了MethodDesc里面。

示例IL

.method private hidebysig static void  Main(string[] args) cil managed {   .entrypoint   .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 )    // 代码大小       19 (0x13)   .maxstack  8   IL_0000:  nop   IL_0001:  ldstr      "Hello, World!"   IL_0006:  call       void [System.Console]System.Console::WriteLine(string)   IL_000b:  nop   IL_000c:  call       string [System.Console]System.Console::ReadLine()   IL_0011:  pop   IL_0012:  ret } // end of method Program::Main 

解构

注意了这里的MethodDesc主要是指函数描述结构,而非函数体。函数描述结构和用IL代码表达的函数体共同被RyuJIT加载和编译。MethodDesc主要的作用是通过CLR把它传入到RyuJIT,然后对MethodDesc描述的函数进行Native Code编译。

结尾

作者:江湖评谈(公众号同名)
.Net 7 内存模型函数描述结构MethoDesc

发表评论

相关文章