.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編譯。



結尾

作者:江湖評談(公衆號同名)
image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章