.net - 方法什么时候可以被 CLR 内联?

标签 .net clr jit inlining

我在应用程序中观察到许多“堆栈内省(introspection)”代码,这些代码通常隐式地依赖于其包含方法被内联以确保其正确性。此类方法通常涉及调用:

  • MethodBase.GetCurrentMethod
  • Assembly.GetCallingAssembly
  • Assembly.GetExecutingAssembly

现在,我发现有关这些方法的信息非常困惑。我听说运行时不会内联调用 GetCurrentMethod 的方法,但我找不到任何相关文档。我曾多次在 StackOverflow 上看到过帖子,例如 this one ,表明 CLR 不会内联跨程序集调用,但 GetCallingAssembly documentation强烈表明否则。

还有备受诟病的 [MethodImpl(MethodImplOptions.NoInlined)],但我不确定 CLR 是否认为这是“请求”或“命令”。

请注意,我是从契约(Contract)的角度询问内联资格不是关于 JITter 的当前实现何时由于实现困难而拒绝考虑方法,或者关于当 JITter 在评估权衡后最终选择内联一个合格的方法时。我已阅读thisthis ,但他们似乎更关注最后两点(偶尔提到了 MethodImpOptions.NoInlined 和“异国情调的 IL 指令”,但这些似乎是作为启发法而不是义务来呈现的)。

什么时候CLR允许内联?

最佳答案

这是一个抖动实现细节,x86 和 x64 抖动的规则略有不同。这在致力于抖动的团队成员的博客文章中被随意记录,但团队当然保留更改规则的权利。看起来您已经找到它们了。

肯定支持来自其他程序集的内联方法,如果不是这样的话,许多 .NET 类将工作得非常糟糕。当您查看为 Console.WriteLine() 生成的机器代码时,您可以看到它的工作原理,当您传递一个简单的字符串时,它通常会被内联。要亲眼看到这一点,您需要切换到发布版本并更改调试器选项。工具+选项、调试、常规,取消选中“抑制模块加载时的 JIT 优化”。

否则没有充分的理由认为 MethodImpOptions.NoInlined 受到诽谤,这几乎就是它存在的首要原因。事实上,它在 .NET 框架中有意用于许多调用内部辅助方法的小型公共(public)方法。它使异常堆栈跟踪更容易诊断。

关于.net - 方法什么时候可以被 CLR 内联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4660004/

相关文章:

.net - CLR JIT 优化违反了因果关系?

c# - CLR 中的确定性 GC?

java - 无用的测试指令?

c# - 在列表中存储相对大量的非持久性数据是不好的做法吗?

.net - Http Agility Pack - 访问 sibling ?

c# - 使用 ExecuteInDefaultAppDomain 调用主函数 C# 控制台应用程序

c++ - 有没有优化 x86 二进制代码的库?

c# - JIT 编译器如何处理值类型?

c# - 绑定(bind)中继器中的所有数据

.net - 将应用程序层拆分为不同的程序集