简体   繁体   English

为什么.NET JIT编译器决定不内联或优化掉没有副作用的空静态方法的调用?

[英]Why would the .NET JIT compiler decide to not inline or optimize away calls to empty static methods that have no side effects?

I think I'm observing the .NET JIT compiler not inlining or optimizing away calls to empty static methods that have no side effects, which is a bit surprising given some bespoken online resources. 我认为我正在观察.NET JIT编译器没有内联或优化对没有副作用的空静态方法的调用,考虑到一些直言不讳的在线资源,这有点令人惊讶。

My environment is Visual Studio 2013 on x64, Windows 8.1, .NET Framework 4.5. 我的环境是x64,Windows 8.1,.NET Framework 4.5上的Visual Studio 2013。

Given this simple test program ( https://ideone.com/2BRCpC ) 鉴于这个简单的测试程序( https://ideone.com/2BRCpC

class Program
{
    static void EmptyBody()
    {
    }

    static void Main()
    {
        EmptyBody();
    }
}

A release build with optimizations of the above program produces the following MSIL for Main and EmptyBody : 通过优化上述程序的发布版本为MainEmptyBody生成以下MSIL:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  call       void Program::EmptyBody()
  IL_0005:  ret
} // end of method Program::Main

.method private hidebysig static void  EmptyBody() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method Program::EmptyBody

It's not surprising that the MSIL contains a call from Main to EmptyBody , since the C# compiler isn't expected to inline or optimize away calls like that. EmptyBody ,MSIL包含从MainEmptyBody的调用,因为C#编译器不会内联或优化掉这样的调用。 However, I thought that the JIT compiler would then inline or optimize away that call. 但是,我认为JIT编译器会内联或优化掉该调用。 But that doesn't seem to happen. 但这似乎并没有发生。

If I run the above program and break into the debugger in Main , the generated assembly is this: 如果我运行上面的程序并进入Main的调试器,生成的程序集是这样的:

00572621  mov         ebp,esp  
00572623  cmp         dword ptr ds:[4320B84h],0  
0057262A  je          00572631  
0057262C  call        73E6AF20  
00572631  call        dword ptr ds:[4321578h]  

The instruction pointer is immediately set to the last line at 00572631, which is the call to EmptyBody . 指令指针立即设置为00572631的最后一行,这是对EmptyBody的调用。 Stepping into EmptyBody , the generated assembly is found to be 步入EmptyBody ,生成的程序集被发现

00BD2651  mov         ebp,esp  
00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  
00BD2661  nop  
00BD2662  pop         ebp  
00BD2663  ret

The instruction pointer is immediately set to the nop line at 00BD2661, which doesn't do anything, and I cannot guess why it's generated in the first place. 指令指针立即设置为00BD2661的nop行,它没有做任何事情,我无法猜测为什么它首先生成。

Given that the two assembly snippets above share the same 4-instruction header, I assume that's just the regular method entry boiler plate where the stack and such is set up. 鉴于上面的两个汇编代码段共享相同的4指令头,我假设这只是常规方法入口样板,其中堆栈等设置。 I'm keen to learn to know what these recurring instructions would do, though: 我很想学会知道这些重复的指令会做什么,但是:

00BD2653  cmp         dword ptr ds:[4B00B84h],0  
00BD265A  je          00BD2661  
00BD265C  call        73E6AF20  

Anyhow, the main question is: Why does the JIT compiler produce assembly that calls the empty-bodied static method EmptyBody ? 无论如何,主要的问题是:为什么JIT编译器生成调用空体静态方法EmptyBody

After digging a bit further, it turns out I can answer this question myself. 经过深入挖掘后,事实证明我可以自己回答这个问题。 As explained at http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx , observing the disassembly of an optimized release build under the debugger will by default affect the JIT compiler. 正如在http://blogs.msdn.com/b/vancem/archive/2006/02/20/535807.aspx中所解释的那样,在调试器下观察优化版本构建的反汇编将默认影响JIT编译器。

Unchecking these 取消选中这些

  • 'Suppress JIT optimization on module load' '抑制模块负载的JIT优化'
  • 'Enable Just My Code' '启用我的代码'

under VS > Tools > Debugging > General, will show the "real" JIT compilation result, which for the call to EmptyBody in my Main above is this: 在VS>工具>调试>常规下,将显示“真正的”JIT编译结果,在我上面的Main调用EmptyBody是这样的:

004C2620  ret

Meaning that the call to EmptyBody is completely removed, which is what was expected and the world is still a happy and somewhat predictable place to live in :) EmptyBody完全删除了对EmptyBody的调用,这是预期的,这个世界仍然是一个快乐且有点可预测的居住地:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM