.Net 7 内存模型函数描述结构MethoDesc
2023-06-13 09:18:11 时间
楔子
从今天开始,讲一些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编译。
相关文章
- Android下载apk异常java.net.SocketTimeoutException: timeout解决办法
- .net 温故知新:【9】.NET日志记录 ILogger使用和原理
- 【水一篇】骚操作之net 6的winform启动的同时启动Net 6 WebApi【同一套代码】
- .net 温故知新:【8】.NET 中的配置从xml转向json
- MATLAB基于深度学习U-net神经网络模型的能谱CT的基物质分解技术研究
- Visual Studio 集成了.NET 升级助手插件
- net掌握Linux环境下的.NET开发(linuxdot)
- 学习.net开发,使用Redis教程(redis教程.net)
- Oracle Database: The Ultimate Connection Guide for .NET Developers(net连接oracle)
- CMySQL与NET技术融会贯通(c mysql .net)
- Net结合MySQL实现强劲的数据库运算(.net 用mysql)
- Redis集群实现高性能NET应用(redis集群 .net)
- Oracle Net服务重新上线,确保数据安全(oracle net重启)
- asp.net中将表单提交到另一页Code-Behind(代码和html在不同的页面)
- asp.net(C#)中给控件添加客户端js事件的方法
- ASP.NET编译执行常见错误及解决方法汇总
- ASP.NET笔记之CKEditor的使用方法
- 浅谈.NET中加密和解密的实现方法分享
- .NET中方法的注意事项总结