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

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.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;
;

这里面可以看到它除了友元类之外,还有一些调试以及非调试的时候所包含的字段。这里的调试指的是Visual Studio里面调试,如果是Windbg这里面的调试字段依然显示不出来。

代码

看下这个简单的例子,在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的主要内容,如果未能解决你的问题,请参考以下文章

7.Java内存模型详解

C++ 类内存模型和对齐

初始化模型时 GPU 内存不足

网易云课堂_C语言程序设计进阶_第六周:程序结构:内存模型(全局变量和局部变量)头文件宏定义函数指针和回调函数,ACL图形库的消息机制

数据结构 线性结构(数组[列表] ,链表 单链表的增删改查**, 线性结构的应用 队列 栈[函数的调用**]),非线性结构 树

JVM内存结构 VS Java内存模型 VS Java对象模型