IKVM.Internal.CodeEmitter.CLRv4_x64_JIT_Workaround C# (CSharp) Method

CLRv4_x64_JIT_Workaround() private method

private CLRv4_x64_JIT_Workaround ( ) : void
return void
        private void CLRv4_x64_JIT_Workaround()
        {
            for (int i = 0; i < code.Count - 2; i++)
            {
                // This is a workaround for https://connect.microsoft.com/VisualStudio/feedback/details/566946/x64-jit-optimization-bug
                //
                // Testing shows that the bug appears to be very specific and requires a comparison of a method argument with zero.
                // For example, the problem goes away when the method argument is first assigned to a local variable and then
                // the comparison (and subsequent use) is done against the local variable.
                //
                // This means we only have to detect these specific patterns:
                //
                //   ldc.i8 0x0        ldarg
                //   ldarg             ldc.i8 0x0
                //   beq/bne           beq/bne
                //
                // The workaround is to replace ldarg with ldarga/ldind.i8. Looking at the generated code by the x86 and x64 JITs
                // this appears to be as efficient as the ldarg and it avoids the x64 bug.
                if (code[i].opcode == OpCodes.Ldc_I8 && code[i].ValueInt64 == 0)
                {
                    short arg;
                    int m;
                    if (i > 0 && MatchLdarg(code[i - 1], out arg) && IsBranchEqNe(code[i + 1].opcode))
                    {
                        m = i - 1;
                    }
                    else if (MatchLdarg(code[i + 1], out arg) && IsBranchEqNe(code[i + 2].opcode))
                    {
                        m = i + 1;
                    }
                    else
                    {
                        continue;
                    }
                    code[m] = new OpCodeWrapper(OpCodes.Ldarga, arg);
                    code.Insert(m + 1, new OpCodeWrapper(OpCodes.Ldind_I8, null));
                }
            }
        }