diff --git a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs index 8f548951eb9133..8d165315e9e2b6 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs @@ -693,7 +693,22 @@ private unsafe void InternalSetValue(object? value, nint flattenedIndex) // value class or primitive type ref byte offsetDataRef = ref Unsafe.Add(ref arrayDataRef, flattenedIndex * pMethodTable->ComponentSize); - if (!RuntimeHelpers.TryUnboxInto(ref offsetDataRef, pElementMethodTable, value)) + if (CastHelpers.IsInstanceOfAny(pElementMethodTable, value) != null) + { + if (pElementMethodTable->IsNullable) + { + RuntimeHelpers.Unbox_Nullable(ref offsetDataRef, pElementMethodTable, value); + } + else if (pElementMethodTable->ContainsGCPointers) + { + Buffer.BulkMoveWithWriteBarrier(ref offsetDataRef, ref value.GetRawData(), pElementMethodTable->GetNumInstanceFieldBytes()); + } + else + { + SpanHelpers.Memmove(ref offsetDataRef, ref value.GetRawData(), pElementMethodTable->GetNumInstanceFieldBytes()); + } + } + else { // Allow enum -> primitive conversion, disallow primitive -> enum conversion MethodTable* thSrc = RuntimeHelpers.GetMethodTable(value); @@ -707,7 +722,7 @@ private unsafe void InternalSetValue(object? value, nint flattenedIndex) if (!RuntimeHelpers.CanPrimitiveWiden(srcType, targetType)) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_PrimitiveWiden); - PrimitiveWiden(ref Unsafe.Unbox(value), ref offsetDataRef, srcType, targetType); + PrimitiveWiden(ref value.GetRawData(), ref offsetDataRef, srcType, targetType); } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 58276a9a11de21..921af0d7967ae4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -323,9 +323,6 @@ internal static unsafe bool ObjectHasComponentSize(object obj) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern unsafe void Unbox_Nullable(ref byte destination, MethodTable* toTypeHnd, object? obj); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern unsafe bool TryUnboxInto(ref byte destination, MethodTable* toTypeHnd, object obj); - // Given an object reference, returns its MethodTable*. // // WARNING: The caller has to ensure that MethodTable* does not get unloaded. The most robust way diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 8014210f110bcd..7a18572cc46a8a 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -353,7 +353,6 @@ FCFuncEnd() #endif // FEATURE_COMINTEROP FCFuncStart(gCastHelpers) - FCFuncElement("CanCastTo_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup) FCFuncElement("IsInstanceOfAny_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup) FCFuncElement("ChkCastAny_NoCacheLookup", ::ChkCastAny_NoCacheLookup) FCFuncElement("Unbox_Helper", ::Unbox_Helper)