From 97c11719dfc8978cdc128703c39db2e6b1df5f8e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 22 Oct 2019 20:23:12 -0700 Subject: [PATCH] Adding SkipInit to Internal.Runtime.CompilerServices.Unsafe (dotnet/coreclr#27377) * Adding SkipInit to Internal.Runtime.CompilerServices.Unsafe * Updating the runtime to handle Unsafe.SkipInit * Updating Decimal.DecCalc to use Unsafe.SkipInit * Removing 'workaround for CS0165' comments Commit migrated from https://github.com/dotnet/coreclr/commit/9bc350f2e7a0b21f1c7d71ffda5ae1797fb5caff --- .../Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs | 2 ++ src/coreclr/src/vm/jitinterface.cpp | 11 ++++++++++ src/coreclr/src/vm/metasig.h | 1 + src/coreclr/src/vm/mscorlib.h | 1 + .../Internal/Runtime/CompilerServices/Unsafe.cs | 13 ++++++++++++ .../src/System/Decimal.DecCalc.cs | 24 ++++++++-------------- 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs index d7c3ab5..c0e0ea1 100644 --- a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs +++ b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs @@ -82,6 +82,8 @@ namespace Internal.IL.Stubs (byte)ILOpcode.ldc_i4_0, (byte)ILOpcode.conv_u, (byte)ILOpcode.prefix1, unchecked((byte)ILOpcode.ceq), (byte)ILOpcode.ret }, Array.Empty(), null); + case "SkipInit": + return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ret }, Array.Empty(), null); } return null; diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index c8bb31f..2b23197 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -7338,6 +7338,17 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } + else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__SKIPINIT)->GetMemberDef()) + { + static BYTE ilcode[] = { CEE_RET }; + + methInfo->ILCode = const_cast(ilcode); + methInfo->ILCodeSize = sizeof(ilcode); + methInfo->maxStack = 0; + methInfo->EHcount = 0; + methInfo->options = (CorInfoOptions)0; + return true; + } return false; } diff --git a/src/coreclr/src/vm/metasig.h b/src/coreclr/src/vm/metasig.h index 42a52e3..2c04b45 100644 --- a/src/coreclr/src/vm/metasig.h +++ b/src/coreclr/src/vm/metasig.h @@ -303,6 +303,7 @@ DEFINE_METASIG(GM(Obj_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, j, M(0))) DEFINE_METASIG(GM(RefT_Int_RetRefT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) i, r(M(0)))) DEFINE_METASIG(GM(RefT_IntPtr_RetRefT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) I, r(M(0)))) DEFINE_METASIG(GM(PtrVoid_Int_RetPtrVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, P(v) i, P(v))) +DEFINE_METASIG(GM(RefT_RetVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)), v)) DEFINE_METASIG_T(SM(SafeHandle_RefBool_RetIntPtr, C(SAFE_HANDLE) r(F), I )) DEFINE_METASIG_T(SM(SafeHandle_RetVoid, C(SAFE_HANDLE), v )) diff --git a/src/coreclr/src/vm/mscorlib.h b/src/coreclr/src/vm/mscorlib.h index d01294b..339b3b9 100644 --- a/src/coreclr/src/vm/mscorlib.h +++ b/src/coreclr/src/vm/mscorlib.h @@ -717,6 +717,7 @@ DEFINE_METHOD(UNSAFE, BYREF_READ_UNALIGNED, ReadUnaligned, GM_Re DEFINE_METHOD(UNSAFE, BYREF_WRITE_UNALIGNED, WriteUnaligned, GM_RefByte_T_RetVoid) DEFINE_METHOD(UNSAFE, PTR_READ_UNALIGNED, ReadUnaligned, GM_PtrVoid_RetT) DEFINE_METHOD(UNSAFE, PTR_WRITE_UNALIGNED, WriteUnaligned, GM_PtrVoid_T_RetVoid) +DEFINE_METHOD(UNSAFE, SKIPINIT, SkipInit, GM_RefT_RetVoid) DEFINE_CLASS(INTERLOCKED, Threading, Interlocked) DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_T, CompareExchange, GM_RefT_T_T_RetT) diff --git a/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs b/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs index 485c157..7c5f9f7 100644 --- a/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs +++ b/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs @@ -422,5 +422,18 @@ namespace Internal.Runtime.CompilerServices // ceq // ret } + + /// + /// Bypasses definite assignment rules by taking advantage of out semantics. + /// + [Intrinsic] + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SkipInit(out T value) + { + throw new PlatformNotSupportedException(); + + // ret + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs index 7f92b1d..eb5deb9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs @@ -990,8 +990,7 @@ ThrowOverflow: // Have to scale by a bunch. Move the number to a buffer where it has room to grow as it's scaled. // - Buf24 bufNum; - _ = &bufNum; // workaround for CS0165 + Unsafe.SkipInit(out Buf24 bufNum); DebugPoison(ref bufNum); bufNum.Low64 = low64; @@ -1340,8 +1339,7 @@ ThrowOverflow: ulong tmp; uint hiProd; - Buf24 bufProd; - _ = &bufProd; // workaround for CS0165 + Unsafe.SkipInit(out Buf24 bufProd); DebugPoison(ref bufProd); if ((d1.High | d1.Mid) == 0) @@ -1922,8 +1920,7 @@ ReturnZero: /// internal static unsafe void VarDecDiv(ref DecCalc d1, ref DecCalc d2) { - Buf12 bufQuo; - _ = &bufQuo; // workaround for CS0165 + Unsafe.SkipInit(out Buf12 bufQuo); DebugPoison(ref bufQuo); uint power; @@ -2024,8 +2021,7 @@ ReturnZero: // Shift both dividend and divisor left by curScale. // - Buf16 bufRem; - _ = &bufRem; // workaround for CS0165 + Unsafe.SkipInit(out Buf16 bufRem); DebugPoison(ref bufRem); bufRem.Low64 = d1.Low64 << curScale; @@ -2094,8 +2090,7 @@ ReturnZero: // // Start by finishing the shift left by curScale. // - Buf12 bufDivisor; - _ = &bufDivisor; // workaround for CS0165 + Unsafe.SkipInit(out Buf12 bufDivisor); DebugPoison(ref bufDivisor); bufDivisor.Low64 = divisor; @@ -2248,8 +2243,7 @@ ThrowOverflow: { d1.uflags = d2.uflags; // Try to scale up dividend to match divisor. - Buf12 bufQuo; - unsafe { _ = &bufQuo; } // workaround for CS0165 + Unsafe.SkipInit(out Buf12 bufQuo); DebugPoison(ref bufQuo); bufQuo.Low64 = d1.Low64; @@ -2309,8 +2303,7 @@ ThrowOverflow: tmp = d2.Mid; int shift = BitOperations.LeadingZeroCount(tmp); - Buf28 b; - _ = &b; // workaround for CS0165 + Unsafe.SkipInit(out Buf28 b); DebugPoison(ref b); b.Buf24.Low64 = d1.Low64 << shift; @@ -2365,8 +2358,7 @@ ThrowOverflow: } else { - Buf12 bufDivisor; - _ = &bufDivisor; // workaround for CS0165 + Unsafe.SkipInit(out Buf12 bufDivisor); DebugPoison(ref bufDivisor); bufDivisor.Low64 = d2.Low64 << shift; -- 2.7.4