欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表

方法调用和类型

创建时间:2012年12月11日 21:33  阅读次数:(5270)
分享到:
从对JIT编译和调用的讨论来看,类型与方法调用是密切相关的。尤其是CLR使用类型的方法表来定位目标方法的地址。考虑下面简单的类型定义:
public class Bob {
publie void f() { }
Static public void UseBob(int n,Bob b)
{
 b.f();
}
}

忽略方法的序言(prolog)和尾声(epilog),JIT编译器将产生下面的IA-32 本机代码,用于UseBob方法:
Mov exc, esi
Call dword prt ds:[352108h]



一个指令把目标对象的引用放进ecx寄存器。这是因为JIT编译器通常使用_fastcall堆栈规则,这可能导致前两个参数被传递到ecx和edx寄存器。第二个指令间接调用目标方法。对于Bob而言,间接寻址是通过方法表中一个特定插槽(slot)--这里是dword ptr[352108h]。

注意,在刚才显示的IA-32 call语句中,Bob方法表插槽的确切地址被加进JIT编译过的方法中。这意味着当派生类型存在时(参见下面代码片断),即使派生类型中存在一个名字和签名恰好匹配的方法,UseIt方法也总是分发到Bob.f。
Public class Steve:Bob
{
Public void f(){}
Static public Exploit(Steve s)
{
Bob.UseIt(s); //调用UseIt,但传递的参数是Steve
}
}

为了使JIT编译器考虑对象的具体类型,需要把方法声声明为virtual。

虚方法【virtual metthod)是一个实例方法,其实现可被派生类型替换或重写。虚方法通过virtual元数据特性的存在进行标识。在开发阶段,当编译器遇到一个对源码中virtual方法的调用时,它发射一个calivirt操作码而不是传统的call操作码。calivirt指令对应的本机代码与call指令对应的本机代码是不同的。如前一节所描述的那样,CIL的call指令静态地绑定本机IA-32 Call指令到特定类型的方法表。相比之下,CIL的callvirt指令产生一个特别的IA-32指令,它将根据目标对象的RuntimeTypeHandle决定使用哪个方法表。这就允许目标对象的具体类型决定调用哪个方法。由于CLR需要对象的具体类型决定使用哪个方法表,因此,虚方法机制不适用丁static方法,此外,如果通过一个null引用执行callvirt指令,将会抛出Svstem.NuliReferenceException异常。

对于虚方法和非虚方法,CLR在方法表中分配的入口项是不同的。方法表有两个相邻的区域:第一个区域用于虚方法,第二个区域用于非虚方法。第一个区域将包含每一个被声明为virtual方法的入口项,不管该方法是在当前类型中,还是在所有基类型与接口中。第二个区域将包含在当前类型中每一个被声明为non-virtual方法的入口项。这种分离允许派生类型的
方法表取代基类型的方法表,用于虚方法分发,原因就是在继承结构中用于特定虚方法的索引都是相同的。

CLR通过目标对象的类型句柄访问所引用的方法表,并根据方法表分发虚方法调用。这样,对象的具体类型就能确切地决定执行哪段代码。如果在前面的例子中,Bob.f方法已经被声明为virtual,Bob.Uselt力法将会是下面这样的:
Move ecx, esi
move eax, dword ptr.[ecx]
call dword ptr [eax + 38h]

第一个mov指令简单地将目标对象的引用存储在IA-32 ecx寄存器中。该指令对于虚调用和非虚调用都是需要的,因为CLR的调用约定需要在调用前将this指针存储在ecx巾。第二个mov指令对于虚方法分发是惟一的。该指令将对象的类型句柄存储在IA-32 eax寄存器中。该类型句柄被IA-32call指令所使用,用于定位目标方法的实际地址。图6.3显示了该调用在内存中的表示。

注意,在刚才描述的IA-32 cali指令中  CLR根据一个固定的methodoffset(方法偏移量)索引类型的方法表。对于一个特定的虚方法,该方法偏移会因为程序的不同执行而可能不同,但在一个运行程序的生命期内将是常量。像字段偏移量一样,方法表偏移量(method table offset】是在类型加载时被计算出来的。每个虚方法的元数据特性都将控制所选择的偏移量。表6.1显示了影响方法表的元数据特性。对于方法偏移量影响最大的是newslot特性。/
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 43+74=? 的结果(结果是:117)
结  果: