问题描述
我在应用中,往往隐含依赖于它们所包含的方法观察到了大量的堆栈内省code的没有的内联为他们的正确性。这种方法通常包括来电:
I've observed a lot of "stack-introspective" code in applications, which often implicitly rely on their containing methods not being inlined for their correctness. Such methods commonly involve calls to:
-
MethodBase.GetCurrentMethod
-
Assembly.GetCallingAssembly
-
Assembly.GetExecutingAssembly
MethodBase.GetCurrentMethod
Assembly.GetCallingAssembly
Assembly.GetExecutingAssembly
现在,我发现周围的这些方法中的信息是非常混乱。我听说在运行时不会内联调用GetCurrentMethod的方法,但我找不到任何文档的效果。我见过的StackOverflow的帖子在多个场合,如这一个,说明CLR不内联跨组件调用,但 GetCallingAssembly
documentation强烈表明并非如此。
Now, I find the information surrounding these methods to be very confusing. I've heard that the run-time will not inline a method that calls GetCurrentMethod, but I can't find any documentation to that effect. I've seen posts on StackOverflow on several occasions, such as this one, indicating the CLR does not inline cross-assembly calls, but the GetCallingAssembly
documentation strongly indicates otherwise.
还有饱受诟病的 [MethodImpl(MethodImplOptions.NoInlining)]
,但我不能确定,如果在CLR认为这是一个要求或命令。
There's also the much-maligned [MethodImpl(MethodImplOptions.NoInlining)]
, but I am unsure if the CLR considers this to be a "request" or a "command."
请注意,我问,从合同的角度看内联的资格的不可以什么时候的抖动下降当前实现考虑,因为执行困难的方法,或者约当抖动终于结束了的选择的评估权衡之后,内联一个合格的方法。我已阅读这和的,但他们似乎更侧重于最后两个点(也有过提及和异域IL指令,但这些似乎是psented作为启发,而不是为$ P $的的义务的)。
Note that I am asking about inlining eligibility from the standpoint of contract, not about when current implementations of the JITter decline to consider methods because of implementation difficulties, or about when the JITter finally ends up choosing to inline an eligible method after assessing the trade-offs. I have read this and this, but they seem to be more focused on the last two points (there are passing mentions of MethodImpOptions.NoInlining and "exotic IL instructions", but these seem to be presented as heuristics rather than as obligations).
当是CLR的允许的执行内联?
When is the CLR allowed to inline?
推荐答案
这是一个抖动的实现细节,x86和x64的抖动有微妙的不同的规则。这是随便记录在工作的抖动,但球队肯定保留更改规则的权利团队成员的博客文章。看起来你已经发现了他们。
It is a jitter implementation detail, the x86 and x64 jitters have subtly different rules. This is casually documented in blog posts of team members that worked on the jitter but the teams certainly reserve the right to alter the rules. Looks like you already found them.
肯定是支持从其他程序集内联方法,很多.NET类的工作会很凄惨,如果事实并非如此。你可以看到它在工作的时候你的Console.WriteLine()生成的机器code,它常常被内联,当你通过一个简单的字符串。要看到自己这一点,你需要切换到发布版本和修改调试器选项。工具+选项,调试,常规,取消选中模块负载燮preSS JIT优化。
Inlining methods from other assemblies is most certainly supported, a lot of the .NET classes would work quite miserably if that wasn't the case. You can see it at work when you look at the machine code generated for Console.WriteLine(), it often gets inlined when you pass a simple string. To see this for yourself, you need to switch to the Release build and change a debugger option. Tools + Options, Debugging, General, untick "Suppress JIT optimization on module load".
,否则就没有很好的理由认为MethodImpOptions.NoInlining非议,这是pretty的多,为什么它存在于首位。这其实是在对大量的调用内部的辅助方法小型公共方法.NET框架有意使用。它使异常堆栈跟踪比较容易诊断。
There is otherwise no good reason to consider MethodImpOptions.NoInlining maligned, it's pretty much why it exists in the first place. It is in fact used intentionally in the .NET framework on lots of small public methods that call an internal helper method. It makes exception stack traces easier to diagnose.
这篇关于当一个方法资格由CLR被内联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!