我在方法内联(交叉组装内联)中测试了一些新的CLR4.0行为,并发现了一些障碍结果:
程序集ClassLib.dll
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
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);
}
}结果:
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()因此,问题是:
Foo和Bar那样内联Baz调用?它们小于32字节的IL,是很好的内衬候选。Bob的JIT内联调用和标记为[MethodImpl(MethodImplOptions.NoInlining)]属性的SomeSecurityCriticalMethod内部调用?GetExecutingAssembly和SomeSecurityCriticalMethod方法调用时,为什么SomeSecurityCriticalMethod返回一个有效的程序集?我希望它执行堆栈遍历来检测正在执行的程序集,但是堆栈将只包含Program.Main()调用,而不包含ClassLib的任何方法,应该返回到ConsoleApp。发布于 2010-04-04 17:08:03
CLR4.0在大多数情况下都有ETW事件,下面是Jit的ETW跟踪,它应该给出MethodJitInliningFailed的原因,这里是如何查看跟踪信息的
https://stackoverflow.com/questions/2533806
复制相似问题