summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2017-02-12 16:50:50 -0800
committerGitHub <noreply@github.com>2017-02-12 16:50:50 -0800
commit7b66079154b3d703225fbd4cc680d4be537592a8 (patch)
treee16455c6c81cd4c632a6de5b8946ab9b9c175dd3 /src
parent7d18263441b2dca466b082ed498f39b768638141 (diff)
downloadcoreclr-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.cs21
-rw-r--r--src/mscorlib/src/System/ReadOnlySpan.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs8
-rw-r--r--src/mscorlib/src/System/Span.cs16
-rw-r--r--src/vm/jitinterface.cpp72
-rw-r--r--src/vm/mscorlib.h2
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