抖动逻辑删除unbox_any [英] Jitter logic to remove unbox_any

查看:234
本文介绍了抖动逻辑删除unbox_any的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我调查的这个C#代码执行:

 公共静态无效测试< T>(对象o),其中T:类
{
T(T)= O为T;
}



等效IL代码为:

 。方法公共静态无效测试与LT;类T>(对象A_0)CIL管理
{
//代码大小13(0xd中)
.maxstack 1
.locals的init(!!牛逼V_0)
IL_0000:ldarg.0
IL_0001:isinst!牛逼
IL_0006:unbox.any!牛逼
IL_000b:stloc.0
IL_000c:RET
} //方法DemoType ::测试


结束

根据这个答案(不必要unbox_any ),任何人都可以向我解释什么确切的逻辑抖动在这里做;究竟怎样的抖动决定忽略在这种特殊情况下(理论上'unbox_any'指令,根据的 MSDN ,一个NullReferenceException应该抛出时,isinst指令产生空,但这在实践中没有发生!)



更新



根据USR答案,汉斯评论,如果在 OBJ 是引用类型, castclass 将被调用,因此没有NRE。



但关于什么下面的案例

 静态无效测试< T>(对象o)其中T:新的()
{
无功可为空= O为int?;
如果(可为空!= NULL)
//做些什么
}

测试和LT;诠释>(NULL);

和等效的IL代码(部分):

  IL_0001:ldarg.0 
IL_0002:isinst值类型[mscorlib程序] System.Nullable`1<&INT32 GT;
IL_0007:unbox.any值类型[mscorlib程序] System.Nullable`1<&INT32 GT;
IL_000c:stloc.0
IL_000d:ldloca.s可为空
IL_000f:呼叫实例布尔值类型[mscorlib程序] System.Nullable`1<&INT32 GT; :: get_HasValue()
IL_0014 :stloc.1
IL_0015:ldloc.1
IL_0016:brfalse.s IL_0024

在这种情况下,它的值类型,为什么NRE没有抛出?


解决方案

当应用到引用类型,unbox.any指令具有作为castclass typeTok同样的效果。




T 约束为引用类型。此指令不在这种情况下抛出NRE。 JIT的不忽略它,因为它规定执行它。该JIT不允许忽略的指令。



的文档具有声明




如果obj是空引用引发NullReferenceException。




这是误导,因为它仅适用于值类型。我引用的第一条语句是毫不含糊的。


I'm investigating the execution of this C# code:

public static void Test<T>(object o) where T : class
{
    T t = o as T;
}

The equivalent IL code is:

.method public static void  Test<class T>(object A_0) cil managed
{
  // Code size       13 (0xd)
  .maxstack  1
  .locals init (!!T V_0)
  IL_0000:  ldarg.0
  IL_0001:  isinst     !!T
  IL_0006:  unbox.any  !!T
  IL_000b:  stloc.0
  IL_000c:  ret
} // end of method DemoType::Test

Based on this answer (unnecessary unbox_any), can anyone explain to me what the exact logic the Jitter is doing here; how exactly does the Jitter decide to ignore the 'unbox_any' instruction in this specific case (theoretically, according to msdn, a NullReferenceException should be thrown when the isinst instruction yields null, but this doesn't happen in practice!)

Update

Based on usr answer and Hans comment, if the obj is a reference type, castclass will be called, and therefore, no NRE.

But what about the following case?

static void Test<T>(object o) where T : new()
    {
        var nullable = o as int?;
        if (nullable != null)
            //do something
    }

Test<int?>(null);

And the equivalent IL code (partial):

IL_0001:  ldarg.0
IL_0002:  isinst     valuetype [mscorlib]System.Nullable`1<int32>
IL_0007:  unbox.any  valuetype [mscorlib]System.Nullable`1<int32>
IL_000c:  stloc.0
IL_000d:  ldloca.s   nullable
IL_000f:  call       instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0014:  stloc.1
IL_0015:  ldloc.1
IL_0016:  brfalse.s  IL_0024

In this case its value type so why NRE not thrown?

解决方案

When applied to a reference type, the unbox.any instruction has the same effect as castclass typeTok.

T is constrained to be a reference type. This instruction does not throw a NRE in this case. The JIT does not "ignore" it, it executes it as specified. The JIT is not allowed to ignore instructions.

The documentation has the statement

NullReferenceException is thrown if obj is a null reference.

which is misleading as it only applies to value types. The first statement that I quoted is unambiguous.

这篇关于抖动逻辑删除unbox_any的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆