4

.Net 7 内存模型函数描述结构MethoDesc - 江湖评谈

 1 year ago
source link: https://www.cnblogs.com/tangyanzhi1111/p/17026428.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

讲一些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里面。

.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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK