Skip to content

Commit

Permalink
Add CopySlow and AssignType
Browse files Browse the repository at this point in the history
  • Loading branch information
huoyaoyuan committed Jun 4, 2024
1 parent 5841ed8 commit a795d59
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 165 deletions.
407 changes: 243 additions & 164 deletions src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal static unsafe class CastHelpers
// Unlike the IsInstanceOfInterface and IsInstanceOfClass functions,
// this test must deal with all kinds of type tests
[DebuggerHidden]
private static object? IsInstanceOfAny(void* toTypeHnd, object? obj)
internal static object? IsInstanceOfAny(void* toTypeHnd, object? obj)
{
if (obj != null)
{
Expand Down
15 changes: 15 additions & 0 deletions src/coreclr/vm/comutilnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,21 @@ extern "C" BOOL QCALLTYPE MethodTable_AreTypesEquivalent(MethodTable* mta, Metho
return bResult;
}

extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo(void* fromTypeHnd, void* toTypeHnd)
{
QCALL_CONTRACT;

BOOL ret = false;

BEGIN_QCALL;

ret = TypeHandle::FromPtr(fromTypeHnd).CanCastTo(TypeHandle::FromPtr(toTypeHnd));

END_QCALL;

return ret;
}

static MethodTable * g_pStreamMT;
static WORD g_slotBeginRead, g_slotEndRead;
static WORD g_slotBeginWrite, g_slotEndWrite;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/comutilnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class MethodTableNative {

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

class StreamNative {
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static const Entry s_QCall[] =
DllImportEntry(QCall_FreeGCHandleForTypeHandle)
DllImportEntry(MethodTable_AreTypesEquivalent)
DllImportEntry(MethodTable_CanCompareBitsOrUseFastGetHashCode)
DllImportEntry(TypeHandle_CanCastTo)
DllImportEntry(ValueType_GetHashCodeStrategy)
DllImportEntry(RuntimeTypeHandle_MakePointer)
DllImportEntry(RuntimeTypeHandle_MakeByRef)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;

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

private static ReadOnlySpan<short> PrimitiveWidenTable =>
[
0x00, // ELEMENT_TYPE_END
0x00, // ELEMENT_TYPE_VOID
0x0004, // ELEMENT_TYPE_BOOLEAN
0x3F88, // ELEMENT_TYPE_CHAR (W = U2, CHAR, I4, U4, I8, U8, R4, R8) (U2 == Char)
0x3550, // ELEMENT_TYPE_I1 (W = I1, I2, I4, I8, R4, R8)
0x3FE8, // ELEMENT_TYPE_U1 (W = CHAR, U1, I2, U2, I4, U4, I8, U8, R4, R8)
0x3540, // ELEMENT_TYPE_I2 (W = I2, I4, I8, R4, R8)
0x3F88, // ELEMENT_TYPE_U2 (W = U2, CHAR, I4, U4, I8, U8, R4, R8)
0x3500, // ELEMENT_TYPE_I4 (W = I4, I8, R4, R8)
0x3E00, // ELEMENT_TYPE_U4 (W = U4, I8, R4, R8)
0x3400, // ELEMENT_TYPE_I8 (W = I8, R4, R8)
0x3800, // ELEMENT_TYPE_U8 (W = U8, R4, R8)
0x3000, // ELEMENT_TYPE_R4 (W = R4, R8)
0x2000, // ELEMENT_TYPE_R8 (W = R8)
];

internal static bool CanPrimitiveWiden(CorElementType srcET, CorElementType dstET)
{
Debug.Assert(srcET.IsPrimitiveType() && dstET.IsPrimitiveType());
if ((int)srcET >= PrimitiveWidenTable.Length)
{
// I or U
return srcET == dstET;
}
return (PrimitiveWidenTable[(int)srcET] & (1 << (int)dstET)) != 0;
}

/// <summary>Provide a fast way to access constant data stored in a module as a ReadOnlySpan{T}</summary>
/// <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>
/// <returns>A ReadOnlySpan{T} of the data stored in the field</returns>
Expand Down

0 comments on commit a795d59

Please sign in to comment.