ddc
联网
平面设计 画册 VI欣赏 包装 CG-插画 搜索 个人网页 Alexa排名 CSS 建站资源 下载专区 JS特效 品牌服装 服装院校 专题欣赏 SEO 图标欣赏 专题
网站建设 域名注册 网站建设 虚拟主机 广州网站设计 域名注册 广州网站建设 上海网站建设 虚拟主机 广州网页设计 虚拟主机 域名注册 acg王国 ACG玩家 品牌设计 上海网站建设
求创科技
网站建设
中国互联
素材出售
中国设计秀
中资源
当前位置:网络学院首页 >> 编程开发 >> .net >> 让JIT运行代码的方法

让JIT运行代码的方法 (3)

来源:中国设计秀    作者:    点击:46     加入收藏    发表评论
0
顶一下
Entry MethodDesc JIT Name

79354bec 7913bd48 PreJIT System.Object.ToString()

793539c0 7913bd50 PreJIT System.Object.Equals(System.Object)

793539b0 7913bd68 PreJIT System.Object.GetHashCode()

7934a4c0 7913bd70 PreJIT System.Object.Finalize()

009130c8 00913070 NONE ConsoleApplication29.Foo.Test()

009130d4 00913078 NONE ConsoleApplication29.Foo..ctor()

很多人已经注意到我们的方法还没有被JIT编译,这就是为什么我们通过间接引用来调用方法的原因之一 :在main方法编译他之前,程序并不知道需要到哪里去调用.这就引出了一个有趣的问题

JIT怎么知道何时编译一个方法?

本质上来说,JIT是延迟加载我们的模块,通过一种被叫做"thunk"(块)的技术,JIT能捕获到我们对方法的第一次调用,所谓thunk是一小段非托管代码,当我们第一次加载某个类型的时候,由CLR通过emit生成.我们将看到thrunk简单的包含对代码或者JIT的调用

图1 : JIT的编译过程

图一中的过程看起来过于简单,但是在实际运用中效率太低.实际系统和途中呈现的流程的差别主要体现在对决策判断上,由于图片的误导,我们似乎觉得trunk中有分支出现;实际上是没有分支的,取而代之的是JIT使用一种叫做back patching的技术

术语"back patching"可能挺眼熟的,因为在GC垃圾处理中也用到了他,这个术语主要的意思是通过更新一个指针来反映信息的变化,当一个方法第一次被调用的时 候,调用方从MethodTable中读取指向一个代码块(thunk)的地址,然后调用这个thunk,,thunk,接着调用JIT.关键的地方在 于,当JIT完成了编译后,将改变MethodTable,使其直接指向已经被JIT编译过的代码,

图2和图3反 映了这个过程完成前后的对比.注意在图中,方法被直接调用,而实际上是通过读取一个经过变化的内存地址来完成的.(译者注:也就是说无论代码是否被JIT 编译,对方法的调用都是通过调用MethodTable中方法地址来实现的,若代码尚未编译,则这个地址指向一个代码块(thunk,),他会帮助你编译 代码,然后修改MethodTable中的指针,指向实际代码)

 

图2:JIT编译前


图3:JIT编译后

现在我们对这一切已经有了一个大概的认识,让我们通过查看调试器来印证我们的知识.你可以使用memory window(debug->windows->memory)输入方法调用的内存地址(i.e. 列表中的009130B8h) ,或者使用registers window (debug->windows->registers (请确认有效地址选项已经打开))来查看所需的数据 .

给你的朋友展示这些玩意,无庸置疑的表现你是办公室里的顶级高手

用调试器单步进入line 0011(第一次调用),我们可以看到在内存地址009130b8中(间接寻址的地址)包含着009130c8,这个地址也许看起来会挺熟悉,这就是指向Thunk的指针,通过!u反编译这个地址,我们甚至可以查看这段非托管代码.

!u 009130C8

Unmanaged code

009130C8 B870309100 mov eax,913070h

009130CD 89ED mov ebp,ebp

009130CF E938EEA2FF jmp 00341F0C

009130D4 B878309100 mov eax,913078h

009130D9 89ED mov ebp,ebp

009130DB E92CEEA2FF jmp 00341F0C

009130E0 0000 add byte ptr [eax],al

009130E2 0000 add byte ptr [eax],al

009130E4 0000 add byte ptr [eax],al

009130E6 0000 add byte ptr [eax],al

[1] [2] [3] [4]
2007-08-27 16:00:00    出处:
Google
网站地图 | 关于我们 | 联系我们 | 网站建设 | 广告服务 | 版权声明 | 免责声明 | 网站公告 | 友情链接 | 留言 | 旧版入口