From eab2b9419abeca3ab01e861d0b23faf4a0a94da8 Mon Sep 17 00:00:00 2001 From: mikedn Date: Mon, 27 Feb 2017 18:40:51 +0200 Subject: [PATCH] Add Unsafe.ReadUnaligned/WriteUnaligned (dotnet/coreclr#9808) Commit migrated from https://github.com/dotnet/coreclr/commit/f569cfa36924ea49c4976a36140c098c8f796bab --- .../src/System/Runtime/CompilerServices/Unsafe.cs | 43 +++++++++++++++++++- src/coreclr/src/vm/jitinterface.cpp | 47 ++++++++++++++++++++++ src/coreclr/src/vm/metasig.h | 4 ++ src/coreclr/src/vm/mscorlib.h | 4 ++ 4 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs index 1268dac..b184cd9 100644 --- a/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs @@ -43,6 +43,7 @@ namespace System.Runtime.CompilerServices { // The body of this function will be replaced by the EE with unsafe code that just returns sizeof !!T // See getILIntrinsicImplementationForUnsafe for how this happens. + typeof(T).ToString(); // Type token used by the actual method body throw new InvalidOperationException(); } @@ -67,7 +68,7 @@ namespace System.Runtime.CompilerServices { // The body of this function will be replaced by the EE with unsafe code!!! // See getILIntrinsicImplementationForUnsafe for how this happens. - typeof(T).ToString(); // Type used by the actual method body + typeof(T).ToString(); // Type token used by the actual method body throw new InvalidOperationException(); } @@ -107,5 +108,45 @@ namespace System.Runtime.CompilerServices // See getILIntrinsicImplementationForUnsafe for how this happens. throw new InvalidOperationException(); } + + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ReadUnaligned(void* source) + { + // The body of this function will be replaced by the EE with unsafe code!!! + // See getILIntrinsicImplementationForUnsafe for how this happens. + typeof(T).ToString(); // Type token used by the actual method body + throw new InvalidOperationException(); + } + + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ReadUnaligned(ref byte source) + { + // The body of this function will be replaced by the EE with unsafe code!!! + // See getILIntrinsicImplementationForUnsafe for how this happens. + typeof(T).ToString(); // Type token used by the actual method body + throw new InvalidOperationException(); + } + + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteUnaligned(void* destination, T value) + { + // The body of this function will be replaced by the EE with unsafe code!!! + // See getILIntrinsicImplementationForUnsafe for how this happens. + typeof(T).ToString(); // Type token used by the actual method body + throw new InvalidOperationException(); + } + + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteUnaligned(ref byte destination, T value) + { + // The body of this function will be replaced by the EE with unsafe code!!! + // See getILIntrinsicImplementationForUnsafe for how this happens. + typeof(T).ToString(); // Type token used by the actual method body + throw new InvalidOperationException(); + } } } diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 322614d..0c05350 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -7053,6 +7053,53 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } + else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_READ_UNALIGNED)->GetMemberDef() || + tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_READ_UNALIGNED)->GetMemberDef()) + { + _ASSERTE(ftn->HasMethodInstantiation()); + Instantiation inst = ftn->GetMethodInstantiation(); + _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + + static const BYTE ilcode[] + { + CEE_LDARG_0, + CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 1, + CEE_LDOBJ, (BYTE)(tokGenericArg), (BYTE)(tokGenericArg >> 8), (BYTE)(tokGenericArg >> 16), (BYTE)(tokGenericArg >> 24), + CEE_RET + }; + + methInfo->ILCode = const_cast(ilcode); + methInfo->ILCodeSize = sizeof(ilcode); + methInfo->maxStack = 2; + methInfo->EHcount = 0; + methInfo->options = (CorInfoOptions)0; + return true; + } + else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_WRITE_UNALIGNED)->GetMemberDef() || + tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_WRITE_UNALIGNED)->GetMemberDef()) + { + _ASSERTE(ftn->HasMethodInstantiation()); + Instantiation inst = ftn->GetMethodInstantiation(); + _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); + mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); + + static const BYTE ilcode[] + { + CEE_LDARG_0, + CEE_LDARG_1, + CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 1, + CEE_STOBJ, (BYTE)(tokGenericArg), (BYTE)(tokGenericArg >> 8), (BYTE)(tokGenericArg >> 16), (BYTE)(tokGenericArg >> 24), + CEE_RET + }; + + methInfo->ILCode = const_cast(ilcode); + methInfo->ILCodeSize = sizeof(ilcode); + methInfo->maxStack = 2; + 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 5933f64..8e0ea0a 100644 --- a/src/coreclr/src/vm/metasig.h +++ b/src/coreclr/src/vm/metasig.h @@ -280,6 +280,10 @@ DEFINE_METASIG(SM(RefDbl_Dbl, r(d) d, v)) DEFINE_METASIG(GM(RefT_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) , M(0))) DEFINE_METASIG(GM(RefT_T, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) M(0), v)) +DEFINE_METASIG(GM(RefByte_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(b), M(0))) +DEFINE_METASIG(GM(RefByte_T_RetVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(b) M(0), v)) +DEFINE_METASIG(GM(PtrVoid_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, P(v), M(0))) +DEFINE_METASIG(GM(PtrVoid_T_RetVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, P(v) 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 38ce80e..7f139a6 100644 --- a/src/coreclr/src/vm/mscorlib.h +++ b/src/coreclr/src/vm/mscorlib.h @@ -931,6 +931,10 @@ DEFINE_METHOD(UNSAFE, BYREF_ADD, Add, NoSig) DEFINE_METHOD(UNSAFE, BYREF_ADD_BYTE_OFFSET, AddByteOffset, NoSig) DEFINE_METHOD(UNSAFE, BYREF_ARE_SAME, AreSame, NoSig) DEFINE_METHOD(UNSAFE, BYREF_INIT_BLOCK_UNALIGNED, InitBlockUnaligned, NoSig) +DEFINE_METHOD(UNSAFE, BYREF_READ_UNALIGNED, ReadUnaligned, GM_RefByte_RetT) +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_CLASS(INTERLOCKED, Threading, Interlocked) DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_T, CompareExchange, GM_RefT_T_T_RetT) -- 2.7.4