Skip to content

Commit a795d59

Browse files
committed
Add CopySlow and AssignType
1 parent 5841ed8 commit a795d59

File tree

6 files changed

+291
-165
lines changed

6 files changed

+291
-165
lines changed

src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs

Lines changed: 243 additions & 164 deletions
Large diffs are not rendered by default.

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal static unsafe class CastHelpers
2929
// Unlike the IsInstanceOfInterface and IsInstanceOfClass functions,
3030
// this test must deal with all kinds of type tests
3131
[DebuggerHidden]
32-
private static object? IsInstanceOfAny(void* toTypeHnd, object? obj)
32+
internal static object? IsInstanceOfAny(void* toTypeHnd, object? obj)
3333
{
3434
if (obj != null)
3535
{

src/coreclr/vm/comutilnative.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,21 @@ extern "C" BOOL QCALLTYPE MethodTable_AreTypesEquivalent(MethodTable* mta, Metho
18091809
return bResult;
18101810
}
18111811

1812+
extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo(void* fromTypeHnd, void* toTypeHnd)
1813+
{
1814+
QCALL_CONTRACT;
1815+
1816+
BOOL ret = false;
1817+
1818+
BEGIN_QCALL;
1819+
1820+
ret = TypeHandle::FromPtr(fromTypeHnd).CanCastTo(TypeHandle::FromPtr(toTypeHnd));
1821+
1822+
END_QCALL;
1823+
1824+
return ret;
1825+
}
1826+
18121827
static MethodTable * g_pStreamMT;
18131828
static WORD g_slotBeginRead, g_slotEndRead;
18141829
static WORD g_slotBeginWrite, g_slotEndWrite;

src/coreclr/vm/comutilnative.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class MethodTableNative {
249249

250250
extern "C" BOOL QCALLTYPE MethodTable_AreTypesEquivalent(MethodTable* mta, MethodTable* mtb);
251251
extern "C" BOOL QCALLTYPE MethodTable_CanCompareBitsOrUseFastGetHashCode(MethodTable* mt);
252+
extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo(void* fromTypeHnd, void* toTypeHnd);
252253
extern "C" INT32 QCALLTYPE ValueType_GetHashCodeStrategy(MethodTable* mt, QCall::ObjectHandleOnStack objHandle, UINT32* fieldOffset, UINT32* fieldSize, MethodTable** fieldMT);
253254

254255
class StreamNative {

src/coreclr/vm/qcallentrypoints.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static const Entry s_QCall[] =
103103
DllImportEntry(QCall_FreeGCHandleForTypeHandle)
104104
DllImportEntry(MethodTable_AreTypesEquivalent)
105105
DllImportEntry(MethodTable_CanCompareBitsOrUseFastGetHashCode)
106+
DllImportEntry(TypeHandle_CanCastTo)
106107
DllImportEntry(ValueType_GetHashCodeStrategy)
107108
DllImportEntry(RuntimeTypeHandle_MakePointer)
108109
DllImportEntry(RuntimeTypeHandle_MakeByRef)

src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics;
45
using System.Reflection;
56
using System.Runtime.InteropServices;
67

@@ -109,6 +110,35 @@ internal static bool IsPrimitiveType(this CorElementType et)
109110
// COR_ELEMENT_TYPE_I1,I2,I4,I8,U1,U2,U4,U8,R4,R8,I,U,CHAR,BOOLEAN
110111
=> ((1 << (int)et) & 0b_0011_0000_0000_0011_1111_1111_1100) != 0;
111112

113+
private static ReadOnlySpan<short> PrimitiveWidenTable =>
114+
[
115+
0x00, // ELEMENT_TYPE_END
116+
0x00, // ELEMENT_TYPE_VOID
117+
0x0004, // ELEMENT_TYPE_BOOLEAN
118+
0x3F88, // ELEMENT_TYPE_CHAR (W = U2, CHAR, I4, U4, I8, U8, R4, R8) (U2 == Char)
119+
0x3550, // ELEMENT_TYPE_I1 (W = I1, I2, I4, I8, R4, R8)
120+
0x3FE8, // ELEMENT_TYPE_U1 (W = CHAR, U1, I2, U2, I4, U4, I8, U8, R4, R8)
121+
0x3540, // ELEMENT_TYPE_I2 (W = I2, I4, I8, R4, R8)
122+
0x3F88, // ELEMENT_TYPE_U2 (W = U2, CHAR, I4, U4, I8, U8, R4, R8)
123+
0x3500, // ELEMENT_TYPE_I4 (W = I4, I8, R4, R8)
124+
0x3E00, // ELEMENT_TYPE_U4 (W = U4, I8, R4, R8)
125+
0x3400, // ELEMENT_TYPE_I8 (W = I8, R4, R8)
126+
0x3800, // ELEMENT_TYPE_U8 (W = U8, R4, R8)
127+
0x3000, // ELEMENT_TYPE_R4 (W = R4, R8)
128+
0x2000, // ELEMENT_TYPE_R8 (W = R8)
129+
];
130+
131+
internal static bool CanPrimitiveWiden(CorElementType srcET, CorElementType dstET)
132+
{
133+
Debug.Assert(srcET.IsPrimitiveType() && dstET.IsPrimitiveType());
134+
if ((int)srcET >= PrimitiveWidenTable.Length)
135+
{
136+
// I or U
137+
return srcET == dstET;
138+
}
139+
return (PrimitiveWidenTable[(int)srcET] & (1 << (int)dstET)) != 0;
140+
}
141+
112142
/// <summary>Provide a fast way to access constant data stored in a module as a ReadOnlySpan{T}</summary>
113143
/// <param name="fldHandle">A field handle that specifies the location of the data to be referred to by the ReadOnlySpan{T}. The Rva of the field must be aligned on a natural boundary of type T</param>
114144
/// <returns>A ReadOnlySpan{T} of the data stored in the field</returns>

0 commit comments

Comments
 (0)