HTML5技术

CoreCLR源码探索(七) JIT的工作原理(入门篇) - q303248153(4)

字号+ 作者:H5之家 来源:H5之家 2017-10-19 08:04 我要评论( )

接下来RyuJIT的后端会给LIR结构中的GenTree节点分配寄存器, 并且根据LIR结构生成汇编指令列表: Instructions as they come out of the schedulerG_M21556_IG01:; func=00, offs=000000H, size=0016H, gcrefRegs=000

接下来RyuJIT的后端会给LIR结构中的GenTree节点分配寄存器, 并且根据LIR结构生成汇编指令列表:

Instructions as they come out of the scheduler G_M21556_IG01: ; func=00, offs=000000H, size=0016H, gcrefRegs=00000000 {}, byrefRegs=00000000 {}, byref, nogc <-- Prolog IG IN001b: 000000 55 push rbp IN001c: 000001 4883EC10 sub rsp, 16 IN001d: 000005 488D6C2410 lea rbp, [rsp+10H] IN001e: 00000A 33C0 xor rax, rax IN001f: 00000C 8945F4 mov dword ptr [rbp-0CH], eax IN0020: 00000F 8945F0 mov dword ptr [rbp-10H], eax IN0021: 000012 48897DF8 mov gword ptr [rbp-08H], rdi G_M21556_IG02: ; func=00, offs=000016H, size=0014H, gcrefRegs=00000000 {}, byrefRegs=00000000 {}, byref, isz IN0001: 000016 48B8100687EA957F0000 mov rax, 0x7F95EA870610 IN0002: 000020 833800 cmp dword ptr [rax], 0 IN0003: 000023 7405 je SHORT G_M21556_IG03 [02479BA8] ptr arg pop 0 IN0004: 000025 E8D6E0B578 call CORINFO_HELP_DBG_IS_JUST_MY_CODE G_M21556_IG03: ; func=00, offs=00002AH, size=0009H, gcrefRegs=00000000 {}, byrefRegs=00000000 {}, byref, isz IN0005: 00002A 90 nop IN0006: 00002B 33FF xor edi, edi IN0007: 00002D 897DF4 mov dword ptr [rbp-0CH], edi IN0008: 000030 90 nop IN0009: 000031 EB13 jmp SHORT G_M21556_IG05 G_M21556_IG04: ; func=00, offs=000033H, size=0013H, gcrefRegs=00000000 {}, byrefRegs=00000000 {}, byref IN000a: 000033 90 nop IN000b: 000034 8B7DF4 mov edi, dword ptr [rbp-0CH] [02479BC0] ptr arg pop 0 IN000c: 000037 E864F7FFFF call System.Console:WriteLine(int) IN000d: 00003C 90 nop IN000e: 00003D 90 nop IN000f: 00003E 8B45F4 mov eax, dword ptr [rbp-0CH] IN0010: 000041 FFC0 inc eax IN0011: 000043 8945F4 mov dword ptr [rbp-0CH], eax G_M21556_IG05: ; func=00, offs=000046H, size=0019H, gcrefRegs=00000000 {}, byrefRegs=00000000 {}, byref, isz IN0012: 000046 8B7DF4 mov edi, dword ptr [rbp-0CH] IN0013: 000049 83FF03 cmp edi, 3 IN0014: 00004C 400F9CC7 setl dil IN0015: 000050 400FB6FF movzx rdi, dil IN0016: 000054 897DF0 mov dword ptr [rbp-10H], edi IN0017: 000057 8B7DF0 mov edi, dword ptr [rbp-10H] IN0018: 00005A 85FF test edi, edi IN0019: 00005C 75D5 jne SHORT G_M21556_IG04 IN001a: 00005E 90 nop G_M21556_IG06: ; func=00, offs=00005FH, size=0006H, epilog, nogc, emitadd IN0022: 00005F 488D6500 lea rsp, [rbp] IN0023: 000063 5D pop rbp IN0024: 000064 C3 ret

最后Emitter把这些指令编码成机器代码就完成了JIT的编译工作.

JIT的数据结构

以下的图片来源于微软提供的JIT入门文档:

第一张是HIR的数据结构

第二张是LIR的数据结构

第三张是CoreCLR中实际的数据结构(HIR和LIR会共用GenTree节点).

JIT的触发

在相当多的.NET书籍中都提到过, CLR中的JIT是懒编译的, 那么具体是如何实现的?
JIT针对每个函数都会提供一个"桩"(Stub), 第一次调用时会触发JIT编译, 第二次调用时会跳转到第一次的编译结果.
流程参考下图:

JIT之前的桩(例子)

0x7fff7c21f5a8: e8 2b 6c fe ff callq 0x7fff7c2061d8

JIT之后的桩(例子)

0x7fff7c21f5a8: e9 a3 87 3a 00 jmp 0x7fff7c5c7d50

具体的汇编代码分析我会在下一篇中给出, 目前你只需要理解"桩"起到的是一个路由的作用.

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • C#使用Xamarin开发可移植移动应用(1.入门与Xamarin.Forms页面),附源码 - GuZhenYin

    C#使用Xamarin开发可移植移动应用(1.入门与Xamarin.Forms页面),附源

    2017-08-09 15:01

  • 【博客园皮肤】-超简洁美观-css源码分享 - Nirvana_zsy

    【博客园皮肤】-超简洁美观-css源码分享 - Nirvana_zsy

    2017-06-28 09:02

  • 每天4亿行SQLite订单大数据测试(源码) - 大石头

    每天4亿行SQLite订单大数据测试(源码) - 大石头

    2017-06-02 13:01

  • 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】 - 一线码农

    使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】 - 一线

    2017-05-29 13:01

网友点评
e