diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index 2216dda0da2fe6..0acf1624c7591b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -410,11 +410,6 @@ private static unsafe IntPtr GetProcAddressWithSuffix(IntPtr hModule, byte* meth return ptr; } - internal static unsafe void CoTaskMemFree(void* p) - { - Marshal.FreeCoTaskMem((IntPtr)p); - } - /// /// Retrieves the function pointer for the current open static delegate that is being called /// diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index cd1395d9115b56..0322db3c1bf7c8 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -182,7 +182,7 @@ internal override bool CleanupRequired internal override void EmitElementCleanup(ILCodeStream codeStream, ILEmitter emitter) { codeStream.Emit(ILOpcode.call, emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); } protected override void AllocNativeToManaged(ILCodeStream codeStream) @@ -240,9 +240,10 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream) protected override void EmitCleanupManaged(ILCodeStream codeStream) { + ILEmitter emitter = _ilCodeStreams.Emitter; LoadNativeValue(codeStream); - codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); + codeStream.Emit(ILOpcode.call, emitter.NewToken( + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); } } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index a59f595311438b..4cd56aea6b17c0 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1491,12 +1491,8 @@ internal override bool CleanupRequired internal override void EmitElementCleanup(ILCodeStream codeStream, ILEmitter emitter) { -#if READYTORUN - throw new NotSupportedException(); -#else codeStream.Emit(ILOpcode.call, emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); -#endif + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); } protected override void TransformManagedToNative(ILCodeStream codeStream) @@ -1613,12 +1609,8 @@ internal override bool CleanupRequired internal override void EmitElementCleanup(ILCodeStream codeStream, ILEmitter emitter) { -#if READYTORUN - throw new NotSupportedException(); -#else codeStream.Emit(ILOpcode.call, emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); -#endif + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); } protected override void TransformManagedToNative(ILCodeStream codeStream) @@ -1765,7 +1757,7 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) LoadNativeValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken( - Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); codeStream.EmitLabel(lNullCheck); #endif @@ -1787,7 +1779,7 @@ internal override void EmitElementCleanup(ILCodeStream codeStream, ILEmitter emi Debug.Assert(_marshallerInstance is null); codeStream.Emit(ILOpcode.call, emitter.NewToken( - InteropTypes.GetMarshal(Context).GetKnownMethod("CoTaskMemFree", null))); + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); } protected override void TransformManagedToNative(ILCodeStream codeStream) @@ -1858,11 +1850,22 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; - Debug.Assert(_marshallerInstance != null); + if (In && !Out && !IsManagedByRef) + { + Debug.Assert(_marshallerInstance != null); - codeStream.EmitLdLoca(_marshallerInstance.Value); - codeStream.Emit(ILOpcode.call, emitter.NewToken( - Marshaller.GetKnownMethod("FreeNative", null))); + codeStream.EmitLdLoca(_marshallerInstance.Value); + codeStream.Emit(ILOpcode.call, emitter.NewToken( + Marshaller.GetKnownMethod("FreeNative", null))); + } + else + { + // The marshaller instance is not guaranteed to be initialized with the latest native value. + // Free the native value directly. + LoadNativeValue(codeStream); + codeStream.Emit(ILOpcode.call, emitter.NewToken( + InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); + } } } diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 3a37699a07f9ab..1a4f265999f13e 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -2016,10 +2016,21 @@ void ILCUTF8Marshaler::EmitClearNative(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; - _ASSERTE(m_dwInstance != LOCAL_NUM_UNUSED); + bool bPassByValueInOnly = IsIn(m_dwMarshalFlags) && !IsOut(m_dwMarshalFlags) && !IsByref(m_dwMarshalFlags); + if (bPassByValueInOnly) + { + _ASSERTE(m_dwInstance != LOCAL_NUM_UNUSED); - pslILEmit->EmitLDLOCA(m_dwInstance); - pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FREE_NATIVE, 1, 0); + pslILEmit->EmitLDLOCA(m_dwInstance); + pslILEmit->EmitCALL(METHOD__UTF8STRINGMARSHALLER__FREE_NATIVE, 1, 0); + } + else + { + // The marshaller instance is not guaranteed to be initialized with the latest native value. + // Free the native value directly. + EmitLoadNativeValue(pslILEmit); + pslILEmit->EmitCALL(METHOD__MARSHAL__FREE_CO_TASK_MEM, 1, 0); + } } LocalDesc ILCSTRMarshaler::GetManagedType() diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf16StringMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf16StringMarshaller.cs index 7d77bedc19ff51..e207bec5f9fcf1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf16StringMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf16StringMarshaller.cs @@ -25,17 +25,7 @@ public unsafe ref struct Utf16StringMarshaller /// The string to marshal. public Utf16StringMarshaller(string? str) { - if (str is null) - { - _nativeValue = null; - return; - } - - // + 1 for null terminator - _nativeValue = (ushort*)Marshal.AllocCoTaskMem((str.Length + 1) * sizeof(ushort)); - - str.CopyTo(new Span(_nativeValue, str.Length)); - _nativeValue[str.Length] = '\0'; // null-terminate + _nativeValue = (ushort*)Marshal.StringToCoTaskMemUni(str); } ///