首页 >> 民生风情

深入理解的编译方式

民生风情  2021-08-25 01:56 字号: 大 中 小

如神州租车、一嗨租车、首汽租赁等。各路平台背后的资本实力均不容小觑。特别是神州专车 CLR只执行本机的机器代码。有两种方式产生本机的机器代码:实时编译(JIT)和预编译方式(产生native image)。

CLR使用类型的方法表来路由所有的方法调用。类型的方法表由多个入口项组成。每个入口项指向一个唯一的存根例程(stub routine)。

初始化时,每个存根例程包含一个对于CLR的JIT编译器的调用(它由内部的PreStubWorker程序公开)。在JIT编译器生成本机代码后,它会重写存根例程,插入一个jmp指令跳转到刚才JIT编译器的代码。只有当要调用某个方法时,JIT编译器才会将CIL的方法体编译为相应的本机机器码版本。这样可以优化程序的工作集。

对于如下的例子:

//using System;

public class Bob{

static int x;

static void a(){x+=2;}

static void b(){x+=3;}

static void c(){x+=4;}

public static void f()

{

c();

b();

a();

}

}

public class MyClass

{

public static void Main()

{

Bob.f();

}

}

用调试器进行JIT调试。

首先,看一下每个方法的汇编显示:

Main()的汇编显示为:

push ebp

mov ebp,esp

//调用Bob.f()方法

call dword ptr ds:[h]

nop

pop ebp

ret

[注]h是Bob.f()在CORINFO_CLASS_STRUCT该内部数据结构中对应的内存地址,该地址中的内容是对应的存根例程的开始地址。

f()的汇编显示为:

push ebp

mov ebp,esp

//调用Bob.c()方法

call dword ptr ds:[h]

//调用Bob.b()方法

call dword ptr ds:[Ch]

//调用Bob.a()方法

call dword ptr ds:[h]

nop

pop ebp

ret

[注]、c、分别为Bob.c()、Bob.b()、Bob.a()在CORINFO_CLASS_STRUCT该内部数据结构中对应的内存地址,该地址中的内容是对应的存根例程的开始地址。

c()的汇编显示为:

push ebp

mov ebp,esp

add dword ptr ds:[Ch],4

nop

pop ebp

ret

[注]c是Bob.x的内存地址。

b()的汇编显示为:

push ebp

mov ebp,esp

add dword ptr ds:[Ch],3

nop

pop ebp

ret

[注]c是Bob.x的内存地址。

a()的汇编显示为:

push ebp

mov ebp,esp

add dword ptr ds:[Ch],2

nop

pop ebp

ret

[注]c是Bob.x的内存地址。

查看本文来源

成都不孕不育诊疗医院
达霏欣用了过敏怎么办
拉稀是怎么回事
推荐资讯