最近 .net 4.6 にアップグレードした後、RyuJit が誤った結果を生成するバグを発見しました。現在、useLegacyJit enabled="true" を app.config に追加することで、この問題を回避することができました。
以下によって生成されたマシンコードをデバッグするにはどうすればよいですか?
VS 2015 RTM で新しいコンソール プロジェクトを作成し、Release、Any CPU に設定し、Prefer 32 ビットのチェックを外し、デバッガーを接続して実行しても、接続せずに実行しても同じ結果が得られます。
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Calculate());
Console.WriteLine(Calculate());
Console.ReadLine();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Value Calculate()
{
bool? _0 = (bool?)null;
bool? _1 = (bool?)true;
if (!Value.IsPresent<bool>(_1))
{
return default(Value);
}
bool? result = null;
result = (_1.Value ? new bool?(false) : result);
if (_0.HasValue && _0.Value)
{
}
return new Value(result);
}
public struct Value
{
bool? _value;
public Value(bool? value)
{
_value = value;
}
public static bool IsPresent<T>(bool? _)
{
return _.HasValue;
}
public override string ToString()
{
return _value.ToString();
}
}
}
}
以下を生成する必要があります: False False
しかし、代わりに以下を生成します: True False
この例の重要な部分は
result = true ? false : result;
これは常に false を返す必要がありますが、出力からわかるように、メソッドが最初に実行されると True が返され、メソッドが 2 回目に実行されると別の答えが返されます。Calculate() メソッドからさらにいくつかの行を削除すると、常に True が返されますが、示されている例は、実際の運用シナリオに最も近いものです。