首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CLR4.0内联策略?(可能是MethodImplOptions.NoInlining的bug )

CLR4.0内联策略?(可能是MethodImplOptions.NoInlining的bug )
EN

Stack Overflow用户
提问于 2010-03-28 17:30:19
回答 1查看 654关注 0票数 3

我在方法内联(交叉组装内联)中测试了一些新的CLR4.0行为,并发现了一些障碍结果:

程序集ClassLib.dll

代码语言:javascript
复制
using System.Diagnostics;
using System;
using System.Reflection;
using System.Security;
using System.Runtime.CompilerServices;

namespace ClassLib
{
  public static class A
  {
    static readonly MethodInfo GetExecuting =
      typeof(Assembly).GetMethod("GetExecutingAssembly");

    public static Assembly Foo(out StackTrace stack) // 13 bytes
    {
      // explicit call to GetExecutingAssembly()
      stack = new StackTrace();
      return Assembly.GetExecutingAssembly();
    }

    public static Assembly Bar(out StackTrace stack) // 25 bytes
    {
      // reflection call to GetExecutingAssembly()
      stack = new StackTrace();
      return (Assembly) GetExecuting.Invoke(null, null);
    }

    public static Assembly Baz(out StackTrace stack) // 9 bytes
    {
      stack = new StackTrace();
      return null;
    }

    public static Assembly Bob(out StackTrace stack) // 13 bytes
    {
      // call of non-inlinable method!
      return SomeSecurityCriticalMethod(out stack);
    }

    [SecurityCritical, MethodImpl(MethodImplOptions.NoInlining)]
    static Assembly SomeSecurityCriticalMethod(out StackTrace stack)
    {
      stack = new StackTrace();
      return Assembly.GetExecutingAssembly();
    }
  }
}

程序集ConsoleApp.exe

代码语言:javascript
复制
using System;
using ClassLib;
using System.Diagnostics;

class Program
{
  static void Main()
  {
    Console.WriteLine("runtime: {0}", Environment.Version);

    StackTrace stack;
    Console.WriteLine("Foo: {0}\n{1}", A.Foo(out stack), stack);
    Console.WriteLine("Bar: {0}\n{1}", A.Bar(out stack), stack);
    Console.WriteLine("Baz: {0}\n{1}", A.Baz(out stack), stack);
    Console.WriteLine("Bob: {0}\n{1}", A.Bob(out stack), stack);
  }
}

结果:

代码语言:javascript
复制
runtime: 4.0.30128.1

Foo: ClassLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
   at ClassLib.A.Foo(StackTrace& stack)
   at Program.Main()

Bar: ClassLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
   at ClassLib.A.Bar(StackTrace& stack)
   at Program.Main()

Baz:
   at Program.Main()

Bob: ClassLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
   at Program.Main()

因此,问题是:

  • 为什么JIT不像FooBar那样内联Baz调用?它们小于32字节的IL,是很好的内衬候选。
  • 为什么Bob的JIT内联调用和标记为[MethodImpl(MethodImplOptions.NoInlining)]属性的SomeSecurityCriticalMethod内部调用?
  • 当内联的GetExecutingAssemblySomeSecurityCriticalMethod方法调用时,为什么SomeSecurityCriticalMethod返回一个有效的程序集?我希望它执行堆栈遍历来检测正在执行的程序集,但是堆栈将只包含Program.Main()调用,而不包含ClassLib的任何方法,应该返回到ConsoleApp
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-04-04 17:08:03

CLR4.0在大多数情况下都有ETW事件,下面是Jit的ETW跟踪,它应该给出MethodJitInliningFailed的原因,这里是如何查看跟踪信息的

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2533806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档