MethodImplOptions.InternalCall有什么意义?

Ani*_*Ani 30 .net clr cil framework-design

BCL中的许多方法都标有 [MethodImpl(MethodImplOptions.InternalCall)]属性.这表明 "方法是在公共语言运行时本身内实现的".

以这种方式设计框架的重点是指定了运行时将被强制实现的显式CIL指令?最终,该属性正在为运行时创建合同义务,但在某种程度上,我觉得这种方式令人困惑,而且不是很明显.

例如,Math.Pow本来可以用这种方式编写(请原谅我非正式的C#+ IL和IL本身,如果它不好的话;这只是一个解释我的观点的样本):

public static double Pow(double x, double y)
{
    ldarg.0
    ldarg.1
    pow // Dedicated CIL instruction
    ret
}
Run Code Online (Sandbox Code Playgroud)

而不是当前的方式:

[MethodImpl(MethodImplOptions.InternalCall)]
public static double Pow(double x, double y);
Run Code Online (Sandbox Code Playgroud)

为什么MethodImplOptions.InternalCall存在?

svi*_*ick 9

我认为一个重要的原因是创建一个新的IL指令非常困难,它可能影响很多工具,包括外部工具(ILGenerator,ilasm,ildasm,PEVerify,Reflector,PostSharp,......).

但是创造一种新InternalCall方法?这几乎和在C#中编写方法一样简单(我假设,我没有看Rotor进行验证)并且它不会影响任何东西.

它不仅仅是创造它,我认为这同样适用于维护.


Mar*_* N. 5

我认为这是为了不要使 CLR 过于复杂。当我第一次研究 CIL 时,我不禁注意到它与汇编语言的相似之处,更重要的是,有限的指令集,几乎就像它们让它直接在处理器上运行一样。

理论上,当 CLR JIT 是Pow您的帖子中包含的示例代码时,它必须向自己发出该指令的本机代码pow,因为没有本机指令(或者是吗?还没有与新的 x86 保持同步)几年前就有指令集)。从性能的角度以及实现的角度来看,调用 mscorlib 来获取代码pow比仅仅内联“粘贴”要容易得多。

或者,他们可以有一个常见 mscorlib 函数的查找表,InternalCall并用对函数本身的调用来替换指令。但话又说回来,并非所有事情都InternalCall那么容易。

我认为这是为了方便而做出的权衡;双方都支持 CLR 可维护性、更统一的 CLI 标准并为调用者提供一定的灵活性。

底线是我还没有开发 CLR,这只是我的想法。我想我会做一些事情。