C# MethodImpl(攻击性在线)-攻击性有多强?
所以我看了一下,我发现它被描述为: 如果可能,该方法应该是内联的 哦,哦,我想,这听起来很有趣-我可以假装我比编译器更聪明,用我邪恶意志的力量和几个方括号强制内联代码,哈,哈,哈 因此,我启动了Visual Studio 2013,创建了一个控制台应用程序,将.NET版本设置为4.5.1,并编写程序以结束所有程序(当然是在C# MethodImpl(攻击性在线)-攻击性有多强?,c#,.net,C#,.net,所以我看了一下,我发现它被描述为: 如果可能,该方法应该是内联的 哦,哦,我想,这听起来很有趣-我可以假装我比编译器更聪明,用我邪恶意志的力量和几个方括号强制内联代码,哈,哈,哈 因此,我启动了Visual Studio 2013,创建了一个控制台应用程序,将.NET版本设置为4.5.1,并编写程序以结束所有程序(当然是在Release模式下编译): 现在,如果我做一个快速ildasm,我会看到: .class public abstract auto ansi sealed beforefie
Release
模式下编译):
现在,如果我做一个快速ildasm,我会看到:
.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.SoHelpful
extends [mscorlib]System.Object
{
.method public hidebysig static int32 GetSomeValueProbablyTwelve() cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldc.i4.s 12
IL_0002: ret
} // end of method SoHelpful::GetSomeValueProbablyTwelve
.method public hidebysig static int32 GetSomeValueLikelyThirteen() cil managed noinlining
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldc.i4.s 13
IL_0002: ret
} // end of method SoHelpful::GetSomeValueLikelyThirteen
.method public hidebysig static int32 GetSomeValueMaybeItIsTwentyEight() cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldc.i4.s 29
IL_0002: ret
} // end of method SoHelpful::GetSomeValueMaybeItIsTwentyEight
} // end of class ConsoleApplication1.SoHelpful
.class private auto ansi beforefieldinit ConsoleApplication1.Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 29 (0x1d)
.maxstack 2
.locals init ([0] int32 twelve,
[1] int32 thirteen,
[2] int32 twentyNine)
IL_0000: call int32 ConsoleApplication1.SoHelpful::GetSomeValueProbablyTwelve()
IL_0005: stloc.0
IL_0006: call int32 ConsoleApplication1.SoHelpful::GetSomeValueLikelyThirteen()
IL_000b: stloc.1
IL_000c: call int32 ConsoleApplication1.SoHelpful::GetSomeValueMaybeItIsTwentyEight()
IL_0011: stloc.2
IL_0012: ldloc.0
IL_0013: ldloc.1
IL_0014: add
IL_0015: ldloc.2
IL_0016: add
IL_0017: call void [mscorlib]System.Console::WriteLine(int32)
IL_001c: ret
} // end of method Program::Main
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
} // end of class ConsoleApplication1.Program
有趣的是,定义了三种方法:
.method public hidebysig static int32 GetSomeValueLikelyThirteen() cil managed noinlining
.method public hidebysig static int32 GetSomeValueProbablyTwelve() cil managed
.method public hidebysig static int32 GetSomeValueMaybeItIsTwentyEight() cil managed
因此,看起来我的攻击性内联属性丢失了
我可以在GetSomeValueLikelThirteen
上看到NoInLine
,但是GetSomeValueProbablyWellve
和GetSomeValueMayBeiTwenty
是相同的
那么发生了什么?我认为有几种可能性:
GetSomeValueProbablyTwelve
不能内联,因此不会因为我愚蠢的属性白痴而困扰JITgetsomevaluemaybeitstwentyweight
可以内联,这就是为什么它在IL中与GetSomeValueProbablyTwelve
相同(因此在这种情况下,我的属性在很大程度上是毫无意义和愚蠢的)C#
中实现那么,有人知道它是哪个吗?MethodImplAttributes.AggressiveInline编译为MethodDef元数据表(ECMA-335 Partition II§22.26)的ImplFlags列中的一个标志。该属性的值列在分区II§23.1.11中,但未记录
aggressiveinline
(表中不存在0x0100的值)
在编译过程中,编译器从元数据中删除属性本身。如果在方法的ImplFlags中设置了0x0100位,则反汇编程序必须实现特殊逻辑以添加回属性。Hmm。。。从命令行编译它,我在
GetSomeValueProbablyTwelve
上获得了aggressiveinline
。现在在VisualStudio下尝试…不,刚刚在VS2013中也尝试过,我也看到了aggressiveInline
。您正在运行哪个版本的ildasm?使用.NET Reflector,我仍然可以在反编译的C#代码中看到AggressiveInline标志(但Reflector没有在IL视图中显示它)arrrggghh,就是它!我使用的是ILDASM的版本4.0.30319.1,但在4.0.30319.18020中它可以工作。我觉得自己很愚蠢。谢谢您的时间。LOLGetSomeValueMaybeistTwentyweight(){return 29;}
啊,谢谢,这是非常有趣的-并且可以解释为什么我需要使用一个新的反汇编程序,因为它需要逻辑来了解这个属性,而不仅仅是转储我发现的所有属性,或者这使得内联分析更容易看到JIT将做什么。它还可以告诉你为什么有些东西不是内联的。
.method public hidebysig static int32 GetSomeValueLikelyThirteen() cil managed noinlining
.method public hidebysig static int32 GetSomeValueProbablyTwelve() cil managed
.method public hidebysig static int32 GetSomeValueMaybeItIsTwentyEight() cil managed