diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs index 89eedc1638a72..7f95b9bd401fc 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs @@ -16,6 +16,21 @@ namespace System.Runtime.CompilerServices /// public static unsafe class Unsafe { + /// + /// Determines the byte offset from origin to target from the given references. + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IntPtr ByteOffset(ref readonly T origin, ref readonly T target) + { + throw new PlatformNotSupportedException(); + + // ldarg .1 + // ldarg .0 + // sub + // ret + } + /// /// Returns a pointer to the given by-ref parameter. /// diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs index b7a1863d3727d..ae2b81bfa418d 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -73,7 +73,6 @@ public static unsafe object RhNewArray(MethodTable* pEEType, int length) } } - [RuntimeExport("RhBox")] public static unsafe object RhBox(MethodTable* pEEType, ref byte data) { // A null can be passed for boxing of a null ref. @@ -207,7 +206,6 @@ public static unsafe void RhUnboxAny(object? o, ref byte data, MethodTable* pUnb // // Unbox helpers with RyuJIT conventions // - [RuntimeExport("RhUnbox2")] public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj) { if ((obj == null) || !UnboxAnyTypeCompare(obj.GetMethodTable(), pUnboxToEEType)) @@ -218,7 +216,6 @@ public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj) return ref obj.GetRawData(); } - [RuntimeExport("RhUnboxNullable")] public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEEType, object obj) { if (obj != null && obj.GetMethodTable() != pUnboxToEEType->NullableType) @@ -228,7 +225,6 @@ public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEE RhUnbox(obj, ref data, pUnboxToEEType); } - [RuntimeExport("RhUnboxTypeTest")] public static unsafe void RhUnboxTypeTest(MethodTable* pType, MethodTable* pBoxType) { Debug.Assert(pType->IsValueType); diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs index 20427987539c3..8425f31f16cc1 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs @@ -63,7 +63,6 @@ internal enum AssignmentVariation // IsInstanceOf test used for unusual cases (naked type parameters, variant generic types) // Unlike the IsInstanceOfInterface and IsInstanceOfClass functions, // this test must deal with all kinds of type tests - [RuntimeExport("RhTypeCast_IsInstanceOfAny")] public static unsafe object? IsInstanceOfAny(MethodTable* pTargetType, object? obj) { if (obj != null) @@ -94,7 +93,6 @@ internal enum AssignmentVariation return IsInstanceOfAny_NoCacheLookup(pTargetType, obj); } - [RuntimeExport("RhTypeCast_IsInstanceOfInterface")] public static unsafe object? IsInstanceOfInterface(MethodTable* pTargetType, object? obj) { Debug.Assert(pTargetType->IsInterface); @@ -184,7 +182,6 @@ internal enum AssignmentVariation return obj; } - [RuntimeExport("RhTypeCast_IsInstanceOfClass")] public static unsafe object? IsInstanceOfClass(MethodTable* pTargetType, object? obj) { Debug.Assert(!pTargetType->IsParameterizedType, "IsInstanceOfClass called with parameterized MethodTable"); @@ -248,7 +245,6 @@ internal enum AssignmentVariation return obj; } - [RuntimeExport("RhTypeCast_IsInstanceOfException")] public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object? obj) { // Based on IsInstanceOfClass @@ -279,7 +275,6 @@ public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object // ChkCast test used for unusual cases (naked type parameters, variant generic types) // Unlike the ChkCastInterface and ChkCastClass functions, // this test must deal with all kinds of type tests - [RuntimeExport("RhTypeCast_CheckCastAny")] public static unsafe object CheckCastAny(MethodTable* pTargetType, object obj) { CastResult result; @@ -307,7 +302,6 @@ public static unsafe object CheckCastAny(MethodTable* pTargetType, object obj) return objRet; } - [RuntimeExport("RhTypeCast_CheckCastInterface")] public static unsafe object CheckCastInterface(MethodTable* pTargetType, object obj) { Debug.Assert(pTargetType->IsInterface); @@ -393,7 +387,6 @@ private static unsafe object CheckCastInterface_Helper(MethodTable* pTargetType, return ThrowInvalidCastException(pTargetType); } - [RuntimeExport("RhTypeCast_CheckCastClass")] public static unsafe object CheckCastClass(MethodTable* pTargetType, object obj) { Debug.Assert(!pTargetType->IsParameterizedType, "CheckCastClass called with parameterized MethodTable"); @@ -411,7 +404,6 @@ public static unsafe object CheckCastClass(MethodTable* pTargetType, object obj) // Optimized helper for classes. Assumes that the trivial cases // has been taken care of by the inlined check - [RuntimeExport("RhTypeCast_CheckCastClassSpecial")] private static unsafe object CheckCastClassSpecial(MethodTable* pTargetType, object obj) { Debug.Assert(!pTargetType->IsParameterizedType, "CheckCastClassSpecial called with parameterized MethodTable"); @@ -761,8 +753,6 @@ private static unsafe void ThrowArrayMismatchException(object?[] array) // // Array stelem/ldelema helpers with RyuJIT conventions // - - [RuntimeExport("RhpLdelemaRef")] public static unsafe ref object? LdelemaRef(object?[] array, nint index, MethodTable* elementType) { Debug.Assert(array is null || array.GetMethodTable()->IsArray, "first argument must be an array"); @@ -794,7 +784,6 @@ private static unsafe void ThrowArrayMismatchException(object?[] array) return ref element; } - [RuntimeExport("RhpStelemRef")] public static unsafe void StelemRef(object?[] array, nint index, object? obj) { // This is supported only on arrays diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs index 363a544f8c74d..6fb23a261f333 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs @@ -216,7 +216,7 @@ public static unsafe void StoreValueTypeField(IntPtr address, object fieldValue, public static unsafe object LoadValueTypeField(IntPtr address, RuntimeTypeHandle fieldType) { - return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address); + return RuntimeExports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address); } public static unsafe object LoadPointerTypeField(IntPtr address, RuntimeTypeHandle fieldType) @@ -236,7 +236,7 @@ public static unsafe void StoreValueTypeField(object obj, int fieldOffset, objec public static unsafe object LoadValueTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType) { ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize)); - return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref address); + return RuntimeExports.RhBox(fieldType.ToMethodTable(), ref address); } public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType) @@ -244,7 +244,7 @@ public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, Ru ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize)); if (fieldType.ToMethodTable()->IsFunctionPointer) - return RuntimeImports.RhBox(MethodTable.Of(), ref address); + return RuntimeExports.RhBox(MethodTable.Of(), ref address); return ReflectionPointer.Box((void*)Unsafe.As(ref address), Type.GetTypeFromHandle(fieldType)); } @@ -285,7 +285,7 @@ public static object LoadValueTypeFieldValueFromValueType(TypedReference typedRe Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType); Debug.Assert(fieldTypeHandle.ToMethodTable()->IsValueType); - return RuntimeImports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset)); + return RuntimeExports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset)); } [CLSCompliant(false)] @@ -391,7 +391,7 @@ public static bool IsInterface(RuntimeTypeHandle type) public static unsafe object Box(RuntimeTypeHandle type, IntPtr address) { - return RuntimeImports.RhBox(type.ToMethodTable(), ref *(byte*)address); + return RuntimeExports.RhBox(type.ToMethodTable(), ref *(byte*)address); } //============================================================================================== diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs index dc30aaecd1f06..09439509355e8 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs @@ -330,7 +330,7 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex for (int i = 0; i < length; i++) { object? value = Unsafe.Add(ref refSourceArray, sourceIndex - i); - if (mustCastCheckEachElement && value != null && RuntimeImports.IsInstanceOf(destinationElementEEType, value) == null) + if (mustCastCheckEachElement && value != null && TypeCast.IsInstanceOfAny(destinationElementEEType, value) == null) throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement); Unsafe.Add(ref refDestinationArray, destinationIndex - i) = value; } @@ -340,7 +340,7 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex for (int i = 0; i < length; i++) { object? value = Unsafe.Add(ref refSourceArray, sourceIndex + i); - if (mustCastCheckEachElement && value != null && RuntimeImports.IsInstanceOf(destinationElementEEType, value) == null) + if (mustCastCheckEachElement && value != null && TypeCast.IsInstanceOfAny(destinationElementEEType, value) == null) throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement); Unsafe.Add(ref refDestinationArray, destinationIndex + i) = value; } @@ -370,7 +370,7 @@ private static unsafe void CopyImplValueTypeArrayToReferenceArray(Array sourceAr ref object refDestinationArray = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(destinationArray)); for (int i = 0; i < length; i++) { - object boxedValue = RuntimeImports.RhBox(sourceElementEEType, ref *pElement); + object boxedValue = RuntimeExports.RhBox(sourceElementEEType, ref *pElement); Unsafe.Add(ref refDestinationArray, destinationIndex + i) = boxedValue; pElement += sourceElementSize; } @@ -457,7 +457,7 @@ private static unsafe void CopyImplValueTypeArrayWithInnerGcRefs(Array sourceArr pDestinationElement -= cbElementSize; } - object boxedValue = RuntimeImports.RhBox(sourceElementEEType, ref *pSourceElement); + object boxedValue = RuntimeExports.RhBox(sourceElementEEType, ref *pSourceElement); if (boxedElements != null) boxedElements[i] = boxedValue; else @@ -768,7 +768,7 @@ internal unsafe nint GetFlattenedIndex(ReadOnlySpan indices) MethodTable* pElementEEType = ElementMethodTable; if (pElementEEType->IsValueType) { - return RuntimeImports.RhBox(pElementEEType, ref element); + return RuntimeExports.RhBox(pElementEEType, ref element); } else { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs index b6fc499829d17..61a2d5367c7cb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs @@ -133,7 +133,7 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje if (dstElementType == srcElementType) { // Rebox the value if the EETypeElementTypes match - dstObject = RuntimeImports.RhBox(dstEEType, ref srcObject.GetRawData()); + dstObject = RuntimeExports.RhBox(dstEEType, ref srcObject.GetRawData()); } else { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs index 45bc2f9e19978..d7837bdc649e1 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs @@ -783,7 +783,7 @@ private unsafe void CopyBackToArray(ref object? src, object?[] dest) } else { - obj = RuntimeImports.RhBox( + obj = RuntimeExports.RhBox( (transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type, ref obj.GetRawData()); } @@ -818,7 +818,7 @@ private unsafe void CopyBackToSpan(Span src, Span dest) } else { - obj = RuntimeImports.RhBox( + obj = RuntimeExports.RhBox( (transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type, ref obj.GetRawData()); } @@ -849,7 +849,7 @@ private unsafe object ReturnTransform(ref byte byref, bool wrapInTargetInvocatio else if ((_returnTransform & Transform.FunctionPointer) != 0) { Debug.Assert(Type.GetTypeFromMethodTable(_returnType).IsFunctionPointer); - obj = RuntimeImports.RhBox(MethodTable.Of(), ref byref); + obj = RuntimeExports.RhBox(MethodTable.Of(), ref byref); } else if ((_returnTransform & Transform.Reference) != 0) { @@ -859,7 +859,7 @@ private unsafe object ReturnTransform(ref byte byref, bool wrapInTargetInvocatio else { Debug.Assert((_returnTransform & (Transform.ByRef | Transform.Nullable)) != 0); - obj = RuntimeImports.RhBox(_returnType, ref byref); + obj = RuntimeExports.RhBox(_returnType, ref byref); } return obj; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs index 8488a99f12a26..b30bfd88ef082 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs @@ -380,7 +380,7 @@ public static unsafe object GetUninitializedObject( if (mt->IsByRefLike) throw new NotSupportedException(SR.NotSupported_ByRefLike); - return RuntimeImports.RhBox(mt, ref target); + return RuntimeExports.RhBox(mt, ref target); } /// diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 15587b4746721..454c5a1e0c4be 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -379,10 +379,6 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) [RuntimeImport(RuntimeLibrary, "RhTypeCast_CheckArrayStore")] internal static extern void RhCheckArrayStore(object array, object? obj); - [MethodImpl(MethodImplOptions.InternalCall)] - [RuntimeImport(RuntimeLibrary, "RhTypeCast_IsInstanceOfAny")] - internal static extern unsafe object IsInstanceOf(MethodTable* pTargetType, object obj); - // // calls to runtime for allocation // These calls are needed in types which cannot use "new" to allocate and need to do it manually @@ -405,10 +401,6 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) [RuntimeImport(RuntimeLibrary, "RhNewString")] internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); - [MethodImpl(MethodImplOptions.InternalCall)] - [RuntimeImport(RuntimeLibrary, "RhBox")] - internal static extern unsafe object RhBox(MethodTable* pEEType, ref byte data); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhUnbox")] internal static extern unsafe void RhUnbox(object? obj, ref byte data, MethodTable* pUnboxToEEType); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs index 1ccb983b64bc3..1854e6ddeb210 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs @@ -630,7 +630,7 @@ public override bool IsInstanceOfType([NotNullWhen(true)] object? o) return false; if (pEEType->IsNullable) pEEType = pEEType->NullableType; - return RuntimeImports.IsInstanceOf(pEEType, o) != null; + return TypeCast.IsInstanceOfAny(pEEType, o) != null; } // diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs index 968e97c425cf8..c19988c9bd678 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs @@ -146,7 +146,7 @@ private unsafe void RegularGetValueTypeHashCode(ref HashCode hashCode, ref byte // of __GetFieldHelper, decodes the unboxing stub pointed to by the slot to the real target // (we already have that part), and calls the entrypoint that expects a byref `this`, and use the // data to decide between calling fast or regular hashcode helper. - var fieldValue = (ValueType)RuntimeImports.RhBox(fieldType, ref fieldData); + var fieldValue = (ValueType)RuntimeExports.RhBox(fieldType, ref fieldData); if (fieldValue != null) { hashCode.Add(fieldValue); diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Buffer.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Buffer.cs new file mode 100644 index 0000000000000..9549be1ae49c7 --- /dev/null +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Buffer.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime; +using System.Runtime.CompilerServices; + +namespace System +{ + public static partial class Buffer + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount) => + RuntimeImports.RhBulkMoveWithWriteBarrier(ref destination, ref source, byteCount); + } +} diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/SpanHelpers.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/SpanHelpers.cs new file mode 100644 index 0000000000000..77c20f716a4d6 --- /dev/null +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/SpanHelpers.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class SpanHelpers + { + [Intrinsic] + public static unsafe void ClearWithoutReferences(ref byte dest, nuint len) + { + Fill(ref dest, 0, len); + } + + [Intrinsic] + internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len) + { + if ((nuint)(nint)Unsafe.ByteOffset(ref src, ref dest) >= len) + for (nuint i = 0; i < len; i++) + Unsafe.Add(ref dest, (nint)i) = Unsafe.Add(ref src, (nint)i); + else + for (nuint i = len; i > 0; i--) + Unsafe.Add(ref dest, (nint)(i - 1)) = Unsafe.Add(ref src, (nint)(i - 1)); + } + + + internal static void Fill(ref byte dest, byte value, nuint len) + { + for (nuint i = 0; i < len; i++) + Unsafe.Add(ref dest, (nint)i) = value; + } + } +} diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj index 9d606a6b75711..b838c2ed7c14b 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj +++ b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj @@ -232,6 +232,8 @@ + + diff --git a/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs b/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs index 4ccaff2d6dd9f..a02c9bbf9da98 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs @@ -33,6 +33,12 @@ public static MethodDesc GetHelperEntryPoint(this TypeSystemContext context, str return helperMethod; } + public static MethodDesc GetCoreLibEntryPoint(this TypeSystemContext context, string namespaceName, string typeName, string methodName, MethodSignature signature) + { + MetadataType owningType = context.SystemModule.GetKnownType(namespaceName, typeName); + return owningType.GetKnownMethod(methodName, signature); + } + public static MethodDesc GetOptionalHelperEntryPoint(this TypeSystemContext context, string typeName, string methodName) { MetadataType helperType = context.GetOptionalHelperType(typeName); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs index d1fc6c593eef8..4d9328f1a34ee 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs @@ -137,6 +137,19 @@ private void CompileSingleMethod(ScannedMethodNode methodCodeNodeNeedingCode) ILScanResults IILScanner.Scan() { + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.BulkWriteBarrier), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.MemCpy), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.MemSet), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.MemZero), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastAny), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastInterface), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastClass), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastClassSpecial), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceAny), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceInterface), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceClass), "Not tracked by scanner"); + _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.IsInstanceOfException), "Not tracked by scanner"); + _dependencyGraph.ComputeMarkedNodes(); _nodeFactory.SetMarkingComplete(); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 8861535467c8c..1d78df875c125 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -73,7 +73,7 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpCheckedAssignRefArm64" : "RhpCheckedAssignRef"; break; case ReadyToRunHelper.BulkWriteBarrier: - mangledName = "RhBuffer_BulkMoveWithWriteBarrier"; + methodDesc = context.GetCoreLibEntryPoint("System", "Buffer", "BulkMoveWithWriteBarrier", null); break; case ReadyToRunHelper.ByRefWriteBarrier: mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpByRefAssignRefArm64" : "RhpByRefAssignRef"; @@ -116,16 +116,16 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, break; case ReadyToRunHelper.Box: case ReadyToRunHelper.Box_Nullable: - mangledName = "RhBox"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhBox", null); break; case ReadyToRunHelper.Unbox: - mangledName = "RhUnbox2"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhUnbox2", null); break; case ReadyToRunHelper.Unbox_Nullable: - mangledName = "RhUnboxNullable"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhUnboxNullable", null); break; case ReadyToRunHelper.Unbox_TypeTest: - mangledName = "RhUnboxTypeTest"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhUnboxTypeTest", null); break; case ReadyToRunHelper.NewMultiDimArr: @@ -143,20 +143,20 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, break; case ReadyToRunHelper.Stelem_Ref: - mangledName = "RhpStelemRef"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "StelemRef", null); break; case ReadyToRunHelper.Ldelema_Ref: - mangledName = "RhpLdelemaRef"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "LdelemaRef", null); break; case ReadyToRunHelper.MemCpy: - mangledName = "RhSpanHelpers_MemCopy"; + methodDesc = context.GetCoreLibEntryPoint("System", "SpanHelpers", "Memmove", null); break; case ReadyToRunHelper.MemSet: - mangledName = "RhSpanHelpers_MemSet"; + methodDesc = context.GetCoreLibEntryPoint("System", "SpanHelpers", "Fill", null); break; case ReadyToRunHelper.MemZero: - mangledName = "RhSpanHelpers_MemZero"; + methodDesc = context.GetCoreLibEntryPoint("System", "SpanHelpers", "ClearWithoutReferences", null); break; case ReadyToRunHelper.NativeMemSet: mangledName = "memset"; @@ -284,29 +284,29 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, break; case ReadyToRunHelper.CheckCastAny: - mangledName = "RhTypeCast_CheckCastAny"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastAny", null); break; case ReadyToRunHelper.CheckCastInterface: - mangledName = "RhTypeCast_CheckCastInterface"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastInterface", null); break; case ReadyToRunHelper.CheckCastClass: - mangledName = "RhTypeCast_CheckCastClass"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastClass", null); break; case ReadyToRunHelper.CheckCastClassSpecial: - mangledName = "RhTypeCast_CheckCastClassSpecial"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastClassSpecial", null); break; case ReadyToRunHelper.CheckInstanceAny: - mangledName = "RhTypeCast_IsInstanceOfAny"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfAny", null); break; case ReadyToRunHelper.CheckInstanceInterface: - mangledName = "RhTypeCast_IsInstanceOfInterface"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfInterface", null); break; case ReadyToRunHelper.CheckInstanceClass: - mangledName = "RhTypeCast_IsInstanceOfClass"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfClass", null); break; case ReadyToRunHelper.IsInstanceOfException: - mangledName = "RhTypeCast_IsInstanceOfException"; + methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfException", null); break; case ReadyToRunHelper.MonitorEnter: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index 611d11e02edd1..00a0d56d48150 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -897,6 +897,7 @@ private void ImportUnbox(int token, ILOpcode opCode) if (opCode == ILOpcode.unbox) { helper = ReadyToRunHelper.Unbox; + _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.Unbox_TypeTest), "Unbox"); } else { @@ -1237,11 +1238,16 @@ private void ImportLoadElement(TypeDesc elementType) private void ImportStoreElement(int token) { - _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.RngChkFail), "stelem"); + ImportStoreElement((TypeDesc)_methodIL.GetObject(token)); } private void ImportStoreElement(TypeDesc elementType) { + if (elementType == null || elementType.IsGCPointer) + { + _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.Stelem_Ref), "stelem"); + } + _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.RngChkFail), "stelem"); } @@ -1254,6 +1260,8 @@ private void ImportAddressOfElement(int token) _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, elementType), "ldelema"); else _dependencies.Add(_factory.NecessaryTypeSymbol(elementType), "ldelema"); + + _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.Ldelema_Ref), "ldelema"); } _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.RngChkFail), "ldelema"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs index 2a1e2a0299950..30ee85041633d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs @@ -175,9 +175,6 @@ ref Unsafe.As(ref source), private const uint BulkMoveWithWriteBarrierChunk = 0x4000; #endif -#if NATIVEAOT - [System.Runtime.RuntimeExport("RhBuffer_BulkMoveWithWriteBarrier")] -#endif internal static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount) { if (byteCount <= BulkMoveWithWriteBarrierChunk) diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs index c4831969ccb0c..e2b33b5d4227f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs @@ -33,9 +33,6 @@ private struct Block16 {} private struct Block64 {} #endif // HAS_CUSTOM_BLOCKS -#if NATIVEAOT - [System.Runtime.RuntimeExport("RhSpanHelpers_MemCopy")] -#endif [Intrinsic] // Unrolled for small constant lengths internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len) { @@ -245,9 +242,6 @@ internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len) Buffer._Memmove(ref dest, ref src, len); } -#if NATIVEAOT - [System.Runtime.RuntimeExport("RhSpanHelpers_MemZero")] -#endif [Intrinsic] // Unrolled for small sizes public static unsafe void ClearWithoutReferences(ref byte dest, nuint len) { @@ -434,9 +428,6 @@ public static unsafe void ClearWithoutReferences(ref byte dest, nuint len) Buffer._ZeroMemory(ref dest, len); } -#if NATIVEAOT - [System.Runtime.RuntimeExport("RhSpanHelpers_MemSet")] -#endif internal static void Fill(ref byte dest, byte value, nuint len) { if (!Vector.IsHardwareAccelerated)