diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-02-12 16:50:50 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-12 16:50:50 -0800 |
commit | 7b66079154b3d703225fbd4cc680d4be537592a8 (patch) | |
tree | e16455c6c81cd4c632a6de5b8946ab9b9c175dd3 /src | |
parent | 7d18263441b2dca466b082ed498f39b768638141 (diff) | |
download | coreclr-7b66079154b3d703225fbd4cc680d4be537592a8.tar.gz coreclr-7b66079154b3d703225fbd4cc680d4be537592a8.tar.bz2 coreclr-7b66079154b3d703225fbd4cc680d4be537592a8.zip |
Add RuntimeHelpers.IsReferenceOrContainsReferences<T>() (#9541)
Rename JitHelpers.ContainsReferences<T>() to RuntimeHelpers.IsReferenceOrContainsReferences<T>() and make it public.
Work towards https://github.com/dotnet/corefx/issues/14047
Diffstat (limited to 'src')
-rw-r--r-- | src/mscorlib/src/System/Collections/Generic/List.cs | 21 | ||||
-rw-r--r-- | src/mscorlib/src/System/ReadOnlySpan.cs | 2 | ||||
-rw-r--r-- | src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs | 8 | ||||
-rw-r--r-- | src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs | 8 | ||||
-rw-r--r-- | src/mscorlib/src/System/Span.cs | 16 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 72 | ||||
-rw-r--r-- | src/vm/mscorlib.h | 2 |
7 files changed, 74 insertions, 55 deletions
diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs index 8e154d748f..82f6e41c36 100644 --- a/src/mscorlib/src/System/Collections/Generic/List.cs +++ b/src/mscorlib/src/System/Collections/Generic/List.cs @@ -12,14 +12,15 @@ ** ** ===========================================================*/ + +using System; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using System.Collections.ObjectModel; +using System.Runtime.CompilerServices; + namespace System.Collections.Generic { - using System; - using System.Diagnostics; - using System.Diagnostics.Contracts; - using System.Collections.ObjectModel; - using Runtime.CompilerServices; - // Implements a variable-size List that uses an array of objects to store the // elements. A List has a capacity, which is the allocated length // of the internal array. As elements are added to a List, the capacity @@ -292,7 +293,7 @@ namespace System.Collections.Generic // Clears the contents of List. public void Clear() { - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { int size = _size; _size = 0; @@ -863,7 +864,7 @@ namespace System.Collections.Generic } } - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references. } @@ -887,7 +888,7 @@ namespace System.Collections.Generic { Array.Copy(_items, index + 1, _items, index, _size - index); } - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { _items[_size] = default(T); } @@ -917,7 +918,7 @@ namespace System.Collections.Generic } _version++; - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { Array.Clear(_items, _size, count); } diff --git a/src/mscorlib/src/System/ReadOnlySpan.cs b/src/mscorlib/src/System/ReadOnlySpan.cs index 76c63d5d8b..ccbca3c118 100644 --- a/src/mscorlib/src/System/ReadOnlySpan.cs +++ b/src/mscorlib/src/System/ReadOnlySpan.cs @@ -103,7 +103,7 @@ namespace System [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe ReadOnlySpan(void* pointer, int length) { - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); if (length < 0) ThrowHelper.ThrowArgumentOutOfRangeException(); diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 509e527ecb..980c2fd469 100644 --- a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -167,6 +167,14 @@ namespace System.Runtime.CompilerServices { { ((CleanupCode)backoutCode)(userData, exceptionThrown); } + + /// <returns>true if given type is reference type or value type that contains references</returns> + static public bool IsReferenceOrContainsReferences<T>() + { + // The body of this function will be replaced by the EE with unsafe code!!! + // See getILIntrinsicImplementation for how this happens. + throw new InvalidOperationException(); + } } } diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs index 080e42f46f..8f847827aa 100644 --- a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs +++ b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs @@ -223,14 +223,6 @@ namespace System.Runtime.CompilerServices { throw new InvalidOperationException(); } - /// <returns>true if given type is reference type or value type that contains references</returns> - static internal bool ContainsReferences<T>() - { - // The body of this function will be replaced by the EE with unsafe code!!! - // See getILIntrinsicImplementation for how this happens. - throw new InvalidOperationException(); - } - static internal ref T GetArrayData<T>(T[] array) { // The body of this function will be replaced by the EE with unsafe code!!! diff --git a/src/mscorlib/src/System/Span.cs b/src/mscorlib/src/System/Span.cs index c77a1994c9..b0d5771c10 100644 --- a/src/mscorlib/src/System/Span.cs +++ b/src/mscorlib/src/System/Span.cs @@ -112,7 +112,7 @@ namespace System [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe Span(void* pointer, int length) { - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); if (length < 0) ThrowHelper.ThrowArgumentOutOfRangeException(); @@ -451,7 +451,7 @@ namespace System public static Span<byte> AsBytes<T>(this Span<T> source) where T : struct { - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); return new Span<byte>( @@ -470,7 +470,7 @@ namespace System public static ReadOnlySpan<byte> AsBytes<T>(this ReadOnlySpan<T> source) where T : struct { - if (JitHelpers.ContainsReferences<T>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); return new ReadOnlySpan<byte>( @@ -493,9 +493,9 @@ namespace System where TFrom : struct where TTo : struct { - if (JitHelpers.ContainsReferences<TFrom>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<TFrom>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom)); - if (JitHelpers.ContainsReferences<TTo>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<TTo>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo)); return new Span<TTo>( @@ -518,9 +518,9 @@ namespace System where TFrom : struct where TTo : struct { - if (JitHelpers.ContainsReferences<TFrom>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<TFrom>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom)); - if (JitHelpers.ContainsReferences<TTo>()) + if (RuntimeHelpers.IsReferenceOrContainsReferences<TTo>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo)); return new ReadOnlySpan<TTo>( @@ -597,7 +597,7 @@ namespace System if (Unsafe.AreSame(ref destination, ref source)) return; - if (!JitHelpers.ContainsReferences<T>()) + if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { fixed (byte* pDestination = &Unsafe.As<T, byte>(ref destination)) { diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index d84dbbb53c..8a0e0f9c06 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -6992,33 +6992,6 @@ bool getILIntrinsicImplementation(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__JIT_HELPERS__CONTAINSREFERENCES)->GetMemberDef()) - { - _ASSERTE(ftn->HasMethodInstantiation()); - Instantiation inst = ftn->GetMethodInstantiation(); - - _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); - TypeHandle typeHandle = inst[0]; - MethodTable * methodTable = typeHandle.GetMethodTable(); - - static const BYTE returnTrue[] = { CEE_LDC_I4_1, CEE_RET }; - static const BYTE returnFalse[] = { CEE_LDC_I4_0, CEE_RET }; - - if (!methodTable->IsValueType() || methodTable->ContainsPointers()) - { - methInfo->ILCode = const_cast<BYTE*>(returnTrue); - } - else - { - methInfo->ILCode = const_cast<BYTE*>(returnFalse); - } - - methInfo->ILCodeSize = sizeof(returnTrue); - methInfo->maxStack = 1; - methInfo->EHcount = 0; - methInfo->options = (CorInfoOptions)0; - return true; - } #endif // FEATURE_SPAN_OF_T return false; @@ -7272,6 +7245,47 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn, return true; } +bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn, + CORINFO_METHOD_INFO * methInfo) +{ + STANDARD_VM_CONTRACT; + + // Precondition: ftn is a method in mscorlib + _ASSERTE(ftn->GetModule()->IsSystem()); + + mdMethodDef tk = ftn->GetMemberDef(); + + if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__IS_REFERENCE_OR_CONTAINS_REFERENCES)->GetMemberDef()) + { + _ASSERTE(ftn->HasMethodInstantiation()); + Instantiation inst = ftn->GetMethodInstantiation(); + + _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); + TypeHandle typeHandle = inst[0]; + MethodTable * methodTable = typeHandle.GetMethodTable(); + + static const BYTE returnTrue[] = { CEE_LDC_I4_1, CEE_RET }; + static const BYTE returnFalse[] = { CEE_LDC_I4_0, CEE_RET }; + + if (!methodTable->IsValueType() || methodTable->ContainsPointers()) + { + methInfo->ILCode = const_cast<BYTE*>(returnTrue); + } + else + { + methInfo->ILCode = const_cast<BYTE*>(returnFalse); + } + + methInfo->ILCodeSize = sizeof(returnTrue); + methInfo->maxStack = 1; + methInfo->EHcount = 0; + methInfo->options = (CorInfoOptions)0; + return true; + } + + return false; +} + //--------------------------------------------------------------------------------------- // //static @@ -7323,6 +7337,10 @@ getMethodInfoHelper( { fILIntrinsic = getILIntrinsicImplementationForVolatile(ftn, methInfo); } + else if (MscorlibBinder::IsClass(pMT, CLASS__RUNTIME_HELPERS)) + { + fILIntrinsic = getILIntrinsicImplementationForRuntimeHelpers(ftn, methInfo); + } if (!fILIntrinsic) { diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h index 78eab6c7d3..8f20078068 100644 --- a/src/vm/mscorlib.h +++ b/src/vm/mscorlib.h @@ -1179,6 +1179,7 @@ DEFINE_CLASS(RUNTIME_HELPERS, CompilerServices, RuntimeHelpers) DEFINE_METHOD(RUNTIME_HELPERS, PREPARE_CONSTRAINED_REGIONS, PrepareConstrainedRegions, SM_RetVoid) DEFINE_METHOD(RUNTIME_HELPERS, PREPARE_CONSTRAINED_REGIONS_NOOP, PrepareConstrainedRegionsNoOP, SM_RetVoid) DEFINE_METHOD(RUNTIME_HELPERS, EXECUTE_BACKOUT_CODE_HELPER, ExecuteBackoutCodeHelper, SM_Obj_Obj_Bool_RetVoid) +DEFINE_METHOD(RUNTIME_HELPERS, IS_REFERENCE_OR_CONTAINS_REFERENCES, IsReferenceOrContainsReferences, NoSig) DEFINE_CLASS(JIT_HELPERS, CompilerServices, JitHelpers) #ifdef _DEBUG @@ -1195,7 +1196,6 @@ DEFINE_METHOD(JIT_HELPERS, UNSAFE_CAST_TO_STACKPTR,UnsafeCastToStackPoi #ifdef FEATURE_SPAN_OF_T DEFINE_METHOD(JIT_HELPERS, BYREF_LESSTHAN, ByRefLessThan, NoSig) DEFINE_METHOD(JIT_HELPERS, GET_ARRAY_DATA, GetArrayData, NoSig) -DEFINE_METHOD(JIT_HELPERS, CONTAINSREFERENCES, ContainsReferences, NoSig) #endif #ifdef FEATURE_SPAN_OF_T |