c# - 为什么我的方法调用 Assembly.GetCallingAssembly() 不是 JIT 内联的?

标签 c# visual-studio inline jit vshost.exe

我正在尝试制作一个简短的 C# 片段来说明 Assembly.GetCallingAssembly() 行为因 JIT 内联而发生的变化 outlined in MSDN .到目前为止,这是我的代码:

class Program
{
   static void Main(string[] args)
   {
       Console.WriteLine( GetAssembly().FullName );
       Console.ReadLine();
   }

   static Assembly GetAssembly()
   {
       return System.Reflection.Assembly.GetCallingAssembly();
   }
}

我在“Release”中构建并开始使用“Start Without Debugging”- 此设置从 this answer 生成代码招致内联。我看到的结果是

ConsoleApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

很明显 GetAssembly() 没有内联到 Main() 中,否则我会将 mscorlib 视为调用程序集。

我已经检查了所有内联标准,但我不明白为什么 GetAssembly() 不会被内联。

是否有可能知道 JIT 编译器决定不内联调用的确切原因?

最佳答案

这是 .NET 3.5 中 Assembly.GetCallingAssembly() 的声明:

[MethodImpl(MethodImplOptions.NoInlining)]
public static Assembly GetCallingAssembly()
{
    StackCrawlMark lookForMyCallersCaller = StackCrawlMark.LookForMyCallersCaller;
    return nGetExecutingAssembly(ref lookForMyCallersCaller);
}

StackCrawlMark 枚举很有趣,当调用者将被内联时,“查找我的调用者调用者”不能很好地工作。在声明枚举的 thread.cs 的 SSCLI20 源代码中有一条注释:

declaring a local var of this enum type and passing it by ref into a function that needs to do a stack crawl will both prevent inlining of the calle [sic] and pass an ESP point to stack crawl to

这与 GetCallingAssembly() 中发生的事情非常匹配,它是一个局部变量并且确实被 ref 传递。不确定机制是什么,但是抖动可以产生一个名为 CORINFO_FLG_BAD_INLINEE 的方法属性。这反过来强制调用 MethodDesc::SetNotInline()。这是一个猜测,这是非常模糊的。

关于c# - 为什么我的方法调用 Assembly.GetCallingAssembly() 不是 JIT 内联的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12910167/

相关文章:

c# - 帮助我以正确的方式编写此事件

C#:从程序安全发送错误报告

visual-studio - 在Visual Studio中进行调试时,为什么会出现 “file is used by another process”错误?

css - 在 joomla 3.3.6 中禁用或删除特定的内联样式

c# - 为什么我的嵌套 HttpModule EndRequest 事件处理程序没有触发?

c# - 使用 Cookie 感知 WebClient

asp.net-mvc - ELMAH 需要 System.Data.SqlServerCe.dll

c++ - 使用 Visual Studio-commander 配置 Qt 4.7.3 失败(返回 #2)

css - 内联css问题

css - 在不调整父宽度的情况下保持子宽度动态