diff --git a/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs
index a390ec6c03bc8..70cff629fc28e 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Object.CoreCLR.cs
@@ -17,7 +17,7 @@ public partial class Object
// so that other object may only call this method on themselves. It is intended to
// support the ICloneable interface.
[Intrinsic]
- protected unsafe object MemberwiseClone()
+ protected internal unsafe object MemberwiseClone()
{
object clone = RuntimeHelpers.AllocateUninitializedClone(this);
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 a931499ac7e2d..6cb159ce33ef4 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
@@ -37,9 +37,23 @@ public static partial class RuntimeHelpers
// cloned when you pass them around, and are always passed by value.
// Of course, reference types are not cloned.
//
- [MethodImpl(MethodImplOptions.InternalCall)]
[return: NotNullIfNotNull(nameof(obj))]
- public static extern object? GetObjectValue(object? obj);
+ public static unsafe object? GetObjectValue(object? obj)
+ {
+ if (obj == null)
+ return null;
+
+ MethodTable* pMT = GetMethodTable(obj);
+
+ if (!pMT->IsValueType || pMT->IsPrimitive)
+ return obj;
+
+ // Technically we could return boxed DateTimes and Decimals without
+ // copying them here, but VB realized that this would be a breaking change
+ // for their customers. So copy them.
+
+ return obj.MemberwiseClone();
+ }
// RunClassConstructor causes the class constructor for the given type to be triggered
// in the current domain. After this call returns, the class constructor is guaranteed to
@@ -487,6 +501,8 @@ internal unsafe struct MethodTable
private const uint enum_flag_Category_Mask = 0x000F0000;
private const uint enum_flag_Category_ValueType = 0x00040000;
private const uint enum_flag_Category_Nullable = 0x00050000;
+ private const uint enum_flag_Category_PrimitiveValueType = 0x00060000; // sub-category of ValueType, Enum or primitive value type
+ private const uint enum_flag_Category_TruePrimitive = 0x00070000; // sub-category of ValueType, Primitive (ELEMENT_TYPE_I, etc.)
private const uint enum_flag_Category_ValueType_Mask = 0x000C0000;
private const uint enum_flag_Category_Interface = 0x000C0000;
// Types that require non-trivial interface cast have this bit set in the category
@@ -565,6 +581,9 @@ public int MultiDimensionalArrayRank
public bool IsByRefLike => (Flags & (enum_flag_HasComponentSize | enum_flag_IsByRefLike)) == enum_flag_IsByRefLike;
+ // Warning! UNLIKE the similarly named Reflection api, this method also returns "true" for Enums.
+ public bool IsPrimitive => (Flags & enum_flag_Category_Mask) is enum_flag_Category_PrimitiveValueType or enum_flag_Category_TruePrimitive;
+
public bool HasInstantiation => (Flags & enum_flag_HasComponentSize) == 0 && (Flags & enum_flag_GenericsMask) != enum_flag_GenericsMask_NonGeneric;
public bool IsGenericTypeDefinition => (Flags & (enum_flag_HasComponentSize | enum_flag_GenericsMask)) == enum_flag_GenericsMask_TypicalInst;
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs
index ee7a472b02410..53819b2cc59ce 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace System.Runtime
{
@@ -26,7 +27,7 @@ namespace System.Runtime
/// properties are instead thread-safe, and safe to use if is not concurrently invoked as well.
///
///
- public struct DependentHandle : IDisposable
+ public partial struct DependentHandle : IDisposable
{
// =========================================================================================
// This struct collects all operations on native DependentHandles. The DependentHandle
@@ -62,8 +63,10 @@ public struct DependentHandle : IDisposable
/// The dependent object instance to associate with .
public DependentHandle(object? target, object? dependent)
{
- // no need to check for null result: InternalInitialize expected to throw OOM.
- _handle = InternalInitialize(target, dependent);
+ IntPtr handle = InternalAlloc(target, dependent);
+ if (handle == 0)
+ handle = InternalAllocWithGCTransition(target, dependent);
+ _handle = handle;
}
///
@@ -71,7 +74,7 @@ public DependentHandle(object? target, object? dependent)
/// and has not yet been disposed.
///
/// This property is thread-safe.
- public readonly bool IsAllocated => (nint)_handle != 0;
+ public readonly bool IsAllocated => _handle != 0;
///
/// Gets or sets the target object instance for the current handle. The target can only be set to a value
@@ -87,7 +90,7 @@ readonly get
{
IntPtr handle = _handle;
- if ((nint)handle == 0)
+ if (handle == 0)
{
ThrowHelper.ThrowInvalidOperationException();
}
@@ -98,7 +101,7 @@ readonly get
{
IntPtr handle = _handle;
- if ((nint)handle == 0 || value is not null)
+ if (handle == 0 || value is not null)
{
ThrowHelper.ThrowInvalidOperationException();
}
@@ -124,7 +127,7 @@ readonly get
{
IntPtr handle = _handle;
- if ((nint)handle == 0)
+ if (handle == 0)
{
ThrowHelper.ThrowInvalidOperationException();
}
@@ -135,7 +138,7 @@ readonly get
{
IntPtr handle = _handle;
- if ((nint)handle == 0)
+ if (handle == 0)
{
ThrowHelper.ThrowInvalidOperationException();
}
@@ -160,7 +163,7 @@ public readonly (object? Target, object? Dependent) TargetAndDependent
{
IntPtr handle = _handle;
- if ((nint)handle == 0)
+ if (handle == 0)
{
ThrowHelper.ThrowInvalidOperationException();
}
@@ -222,16 +225,26 @@ public void Dispose()
// (if not already there) and frees the handle if needed.
IntPtr handle = _handle;
- if ((nint)handle != 0)
+ if (handle != 0)
{
- _handle = IntPtr.Zero;
+ _handle = 0;
- InternalFree(handle);
+ if (!InternalFree(handle))
+ {
+ InternalFreeWithGCTransition(handle);
+ }
}
}
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern IntPtr InternalInitialize(object? target, object? dependent);
+ private static extern IntPtr InternalAlloc(object? target, object? dependent);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static IntPtr InternalAllocWithGCTransition(object? target, object? dependent)
+ => _InternalAllocWithGCTransition(ObjectHandleOnStack.Create(ref target), ObjectHandleOnStack.Create(ref dependent));
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DependentHandle_InternalAllocWithGCTransition")]
+ private static partial IntPtr _InternalAllocWithGCTransition(ObjectHandleOnStack target, ObjectHandleOnStack dependent);
#if DEBUG
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -258,6 +271,13 @@ public void Dispose()
private static extern void InternalSetTargetToNull(IntPtr dependentHandle);
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void InternalFree(IntPtr dependentHandle);
+ private static extern bool InternalFree(IntPtr dependentHandle);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void InternalFreeWithGCTransition(IntPtr dependentHandle)
+ => _InternalFreeWithGCTransition(dependentHandle);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DependentHandle_InternalFreeWithGCTransition")]
+ private static partial void _InternalFreeWithGCTransition(IntPtr dependentHandle);
}
}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs
index c62d6aeb75fe4..1238b029598d0 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs
@@ -7,11 +7,39 @@ namespace System.Runtime.InteropServices
{
public partial struct GCHandle
{
+ internal static IntPtr InternalAlloc(object? value, GCHandleType type)
+ {
+ IntPtr handle = _InternalAlloc(value, type);
+ if (handle == 0)
+ handle = InternalAllocWithGCTransition(value, type);
+ return handle;
+ }
+
[MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern IntPtr InternalAlloc(object? value, GCHandleType type);
+ private static extern IntPtr _InternalAlloc(object? value, GCHandleType type);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static IntPtr InternalAllocWithGCTransition(object? value, GCHandleType type)
+ => _InternalAllocWithGCTransition(ObjectHandleOnStack.Create(ref value), type);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCHandle_InternalAllocWithGCTransition")]
+ private static partial IntPtr _InternalAllocWithGCTransition(ObjectHandleOnStack value, GCHandleType type);
+
+ internal static void InternalFree(IntPtr handle)
+ {
+ if (!_InternalFree(handle))
+ InternalFreeWithGCTransition(handle);
+ }
[MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern void InternalFree(IntPtr handle);
+ private static extern bool _InternalFree(IntPtr handle);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void InternalFreeWithGCTransition(IntPtr dependentHandle)
+ => _InternalFreeWithGCTransition(dependentHandle);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCHandle_InternalFreeWithGCTransition")]
+ private static partial void _InternalFreeWithGCTransition(IntPtr dependentHandle);
#if DEBUG
// The runtime performs additional checks in debug builds
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs
index 43c680cedfe0d..2ccb7ff256847 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs
@@ -24,8 +24,11 @@ public static partial class Marshal
internal static Guid IID_IUnknown = new Guid(0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
#endif //FEATURE_COMINTEROP
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern int SizeOfHelper(Type t, bool throwIfNotMarshalable);
+ internal static int SizeOfHelper(RuntimeType t, [MarshalAs(UnmanagedType.Bool)] bool throwIfNotMarshalable)
+ => SizeOfHelper(new QCallTypeHandle(ref t), throwIfNotMarshalable);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MarshalNative_SizeOfHelper")]
+ private static partial int SizeOfHelper(QCallTypeHandle t, [MarshalAs(UnmanagedType.Bool)] bool throwIfNotMarshalable);
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "Trimming doesn't affect types eligible for marshalling. Different exception for invalid inputs doesn't matter.")]
@@ -234,24 +237,95 @@ private static void PrelinkCore(MethodInfo m)
/// true, this routine will call DestroyStructure() first.
///
[RequiresDynamicCode("Marshalling code for the object might not be available. Use the StructureToPtr overload instead.")]
- [MethodImpl(MethodImplOptions.InternalCall)]
[EditorBrowsable(EditorBrowsableState.Never)]
- public static extern void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld);
+ public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)
+ {
+ ArgumentNullException.ThrowIfNull(ptr);
+ ArgumentNullException.ThrowIfNull(structure);
+
+ MethodTable* pMT = RuntimeHelpers.GetMethodTable(structure);
+
+ if (pMT->HasInstantiation)
+ throw new ArgumentException(SR.Argument_NeedNonGenericObject, nameof(structure));
+
+ delegate*[ structMarshalStub;
+ nuint size;
+ if (!TryGetStructMarshalStub((IntPtr)pMT, &structMarshalStub, &size))
+ throw new ArgumentException(SR.Argument_MustHaveLayoutOrBeBlittable, nameof(structure));
+
+ if (structMarshalStub != null)
+ {
+ if (fDeleteOld)
+ {
+ structMarshalStub(ref structure.GetRawData(), (byte*)ptr, MarshalOperation.Cleanup, ref Unsafe.NullRef());
+ }
+
+ structMarshalStub(ref structure.GetRawData(), (byte*)ptr, MarshalOperation.Marshal, ref Unsafe.NullRef());
+ }
+ else
+ {
+ Buffer.Memmove(ref *(byte*)ptr, ref structure.GetRawData(), size);
+ }
+ }
///
/// Helper function to copy a pointer into a preallocated structure.
///
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void PtrToStructureHelper(IntPtr ptr, object structure, bool allowValueClasses);
+ private static unsafe void PtrToStructureHelper(IntPtr ptr, object structure, bool allowValueClasses)
+ {
+ MethodTable* pMT = RuntimeHelpers.GetMethodTable(structure);
+
+ if (!allowValueClasses && pMT->IsValueType)
+ throw new ArgumentException(SR.Argument_StructMustNotBeValueClass, nameof(structure));
+
+ delegate*][ structMarshalStub;
+ nuint size;
+ if (!TryGetStructMarshalStub((IntPtr)pMT, &structMarshalStub, &size))
+ throw new ArgumentException(SR.Argument_MustHaveLayoutOrBeBlittable, nameof(structure));
+
+ if (structMarshalStub != null)
+ {
+ structMarshalStub(ref structure.GetRawData(), (byte*)ptr, MarshalOperation.Unmarshal, ref Unsafe.NullRef());
+ }
+ else
+ {
+ Buffer.Memmove(ref structure.GetRawData(), ref *(byte*)ptr, size);
+ }
+ }
///
/// Frees all substructures pointed to by the native memory block.
- /// "structuretype" is used to provide layout information.
+ /// nameof(structuretype) is used to provide layout information.
///
[RequiresDynamicCode("Marshalling code for the object might not be available. Use the DestroyStructure overload instead.")]
- [MethodImpl(MethodImplOptions.InternalCall)]
[EditorBrowsable(EditorBrowsableState.Never)]
- public static extern void DestroyStructure(IntPtr ptr, Type structuretype);
+ public static unsafe void DestroyStructure(IntPtr ptr, Type structuretype)
+ {
+ ArgumentNullException.ThrowIfNull(ptr);
+ ArgumentNullException.ThrowIfNull(structuretype);
+
+ if (structuretype is not RuntimeType rt)
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(structuretype));
+
+ if (rt.IsGenericType)
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structuretype));
+
+ delegate*][ structMarshalStub;
+ nuint size;
+ if (!TryGetStructMarshalStub(rt.GetUnderlyingNativeHandle(), &structMarshalStub, &size))
+ throw new ArgumentException(SR.Argument_MustHaveLayoutOrBeBlittable, nameof(structuretype));
+
+ GC.KeepAlive(rt);
+
+ if (structMarshalStub != null)
+ {
+ structMarshalStub(ref Unsafe.NullRef(), (byte*)ptr, MarshalOperation.Cleanup, ref Unsafe.NullRef());
+ }
+ }
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MarshalNative_TryGetStructMarshalStub")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static unsafe partial bool TryGetStructMarshalStub(IntPtr th, delegate*][* structMarshalStub, nuint* size);
// Note: Callers are required to keep obj alive
internal static unsafe bool IsPinnable(object? obj)
diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
index 3f7527f06cfc2..c723fed4de9b3 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
@@ -4,6 +4,7 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
using System.Text;
namespace System.StubHelpers
@@ -461,16 +462,37 @@ internal static unsafe string ConvertToManaged(IntPtr nativeHome, int length)
} // class WSTRBufferMarshaler
#if FEATURE_COMINTEROP
- internal static class ObjectMarshaler
+ internal static partial class ObjectMarshaler
{
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern void ConvertToNative(object objSrc, IntPtr pDstVariant);
+ internal static void ConvertToNative(object objSrc, IntPtr pDstVariant)
+ {
+ ConvertToNative(ObjectHandleOnStack.Create(ref objSrc), pDstVariant);
+ }
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern object ConvertToManaged(IntPtr pSrcVariant);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ObjectMarshaler_ConvertToNative")]
+ private static partial void ConvertToNative(ObjectHandleOnStack objSrc, IntPtr pDstVariant);
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern void ClearNative(IntPtr pVariant);
+ internal static object ConvertToManaged(IntPtr pSrcVariant)
+ {
+ object? retObject = null;
+ ConvertToManaged(pSrcVariant, ObjectHandleOnStack.Create(ref retObject));
+ return retObject!;
+ }
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ObjectMarshaler_ConvertToManaged")]
+ private static partial void ConvertToManaged(IntPtr pSrcVariant, ObjectHandleOnStack retObject);
+
+ internal static unsafe void ClearNative(IntPtr pVariant)
+ {
+ if (pVariant != IntPtr.Zero)
+ {
+ Interop.OleAut32.VariantClear(pVariant);
+
+ // VariantClear resets the instance to VT_EMPTY (0)
+ // COMPAT: Clear the remaining memory for compat. The instance remains set to VT_EMPTY (0).
+ *(ComVariant*)pVariant = default;
+ }
+ }
} // class ObjectMarshaler
#endif // FEATURE_COMINTEROP
@@ -870,7 +892,7 @@ private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags)
// of pManagedHome is not marshalable. That's intentional because we
// want to maintain the original behavior where this was indicated
// by TypeLoadException during the actual field marshaling.
- int allocSize = Marshal.SizeOfHelper(pManagedHome.GetType(), false);
+ int allocSize = Marshal.SizeOfHelper((RuntimeType)pManagedHome.GetType(), false);
IntPtr pNativeHome = Marshal.AllocCoTaskMem(allocSize);
// marshal the object as class with layout (UnmanagedType.LPStruct)
@@ -1001,37 +1023,12 @@ internal void ClearNative(IntPtr pNativeHome)
}
} // struct AsAnyMarshaler
- [StructLayout(LayoutKind.Sequential)]
- internal struct NativeVariant
+ // Constants for direction argument of struct marshalling stub.
+ internal static class MarshalOperation
{
- private ushort vt;
- private ushort wReserved1;
- private ushort wReserved2;
- private ushort wReserved3;
-
- // The union portion of the structure contains at least one 64-bit type that on some 32-bit platforms
- // (notably ARM) requires 64-bit alignment. So on 32-bit platforms we'll actually size the variant
- // portion of the struct with an Int64 so the type loader notices this requirement (a no-op on x86,
- // but on ARM it will allow us to correctly determine the layout of native argument lists containing
- // VARIANTs). Note that the field names here don't matter: none of the code refers to these fields,
- // the structure just exists to provide size information to the IL marshaler.
-#if TARGET_64BIT
- private IntPtr data1;
- private IntPtr data2;
-#else
- private long data1;
-#endif
- } // struct NativeVariant
-
- // This NativeDecimal type is very similar to the System.Decimal type, except it requires an 8-byte alignment
- // like the native DECIMAL type instead of the 4-byte requirement of the System.Decimal type.
- [StructLayout(LayoutKind.Sequential)]
- internal struct NativeDecimal
- {
- private ushort reserved;
- private ushort signScale;
- private uint hi32;
- private ulong lo64;
+ internal const int Marshal = 0;
+ internal const int Unmarshal = 1;
+ internal const int Cleanup = 2;
}
internal abstract class CleanupWorkListElement
@@ -1111,7 +1108,7 @@ public IntPtr AddRef()
}
} // class CleanupWorkListElement
- internal static class StubHelpers
+ internal static partial class StubHelpers
{
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetDelegateTarget(Delegate pThis);
@@ -1190,8 +1187,8 @@ internal static void SetPendingExceptionObject(Exception? exception)
s_pendingExceptionObject = exception;
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern IntPtr CreateCustomMarshalerHelper(IntPtr pMD, int paramToken, IntPtr hndManagedType);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshalerHelper")]
+ internal static partial IntPtr CreateCustomMarshalerHelper(IntPtr pMD, int paramToken, IntPtr hndManagedType);
//-------------------------------------------------------
// SafeHandle Helpers
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Monitor.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Monitor.CoreCLR.cs
index 41183e9be8587..fdfc1c333e971 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Monitor.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Monitor.CoreCLR.cs
@@ -144,8 +144,9 @@ public static bool IsEntered(object obj)
**
** Exceptions: ArgumentNullException if object is null.
========================================================================*/
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern bool ObjWait(int millisecondsTimeout, object obj);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Monitor_Wait")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static partial bool Wait(ObjectHandleOnStack obj, int millisecondsTimeout);
[UnsupportedOSPlatform("browser")]
public static bool Wait(object obj, int millisecondsTimeout)
@@ -153,7 +154,7 @@ public static bool Wait(object obj, int millisecondsTimeout)
ArgumentNullException.ThrowIfNull(obj);
ArgumentOutOfRangeException.ThrowIfLessThan(millisecondsTimeout, -1);
- return ObjWait(millisecondsTimeout, obj);
+ return Wait(ObjectHandleOnStack.Create(ref obj), millisecondsTimeout);
}
/*========================================================================
@@ -161,26 +162,26 @@ public static bool Wait(object obj, int millisecondsTimeout)
* Exceptions: SynchronizationLockException if this method is not called inside
* a synchronized block of code.
========================================================================*/
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void ObjPulse(object obj);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Monitor_Pulse")]
+ private static partial void Pulse(ObjectHandleOnStack obj);
public static void Pulse(object obj)
{
ArgumentNullException.ThrowIfNull(obj);
- ObjPulse(obj);
+ Pulse(ObjectHandleOnStack.Create(ref obj));
}
/*========================================================================
** Sends a notification to all waiting objects.
========================================================================*/
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void ObjPulseAll(object obj);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Monitor_PulseAll")]
+ private static partial void PulseAll(ObjectHandleOnStack obj);
public static void PulseAll(object obj)
{
ArgumentNullException.ThrowIfNull(obj);
- ObjPulseAll(obj);
+ PulseAll(ObjectHandleOnStack.Create(ref obj));
}
///
@@ -188,7 +189,7 @@ public static void PulseAll(object obj)
///
public static long LockContentionCount => GetLockContentionCount() + Lock.ContentionCount;
- [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ObjectNative_GetMonitorLockContentionCount")]
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Monitor_GetLockContentionCount")]
private static partial long GetLockContentionCount();
}
}
diff --git a/src/coreclr/classlibnative/bcltype/objectnative.cpp b/src/coreclr/classlibnative/bcltype/objectnative.cpp
index 01192057756d7..4622955b44adf 100644
--- a/src/coreclr/classlibnative/bcltype/objectnative.cpp
+++ b/src/coreclr/classlibnative/bcltype/objectnative.cpp
@@ -20,52 +20,6 @@
#include "eeconfig.h"
-/********************************************************************/
-/* gets an object's 'value'. For normal classes, with reference
- based semantics, this means the object's pointer. For boxed
- primitive types, it also means just returning the pointer (because
- they are immutable), for other value class, it means returning
- a boxed copy. */
-
-FCIMPL1(Object*, ObjectNative::GetObjectValue, Object* obj)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- INJECT_FAULT(FCThrow(kOutOfMemoryException););
- }
- CONTRACTL_END;
-
- VALIDATEOBJECT(obj);
-
- if (obj == 0)
- return(obj);
-
- MethodTable* pMT = obj->GetMethodTable();
- // optimize for primitive types since GetVerifierCorElementType is slow.
- if (pMT->IsTruePrimitive() || TypeHandle(pMT).GetVerifierCorElementType() != ELEMENT_TYPE_VALUETYPE) {
- return(obj);
- }
-
- Object* retVal = NULL;
- OBJECTREF objRef(obj);
- HELPER_METHOD_FRAME_BEGIN_RET_1(objRef); // Set up a frame
-
- // Technically we could return boxed DateTimes and Decimals without
- // copying them here, but VB realized that this would be a breaking change
- // for their customers. So copy them.
- //
- // MethodTable::Box is a cleaner way to copy value class, but it is slower than following code.
- //
- retVal = OBJECTREFToObject(AllocateObject(pMT));
- CopyValueClass(retVal->GetData(), objRef->GetData(), pMT);
- HELPER_METHOD_FRAME_END();
-
- return(retVal);
-}
-FCIMPLEND
-
-
NOINLINE static INT32 GetHashCodeHelper(OBJECTREF objRef)
{
DWORD idx = 0;
@@ -292,56 +246,54 @@ FCIMPL1(Object*, ObjectNative::AllocateUninitializedClone, Object* pObjUNSAFE)
}
FCIMPLEND
-FCIMPL2(FC_BOOL_RET, ObjectNative::WaitTimeout, INT32 Timeout, Object* pThisUNSAFE)
+extern "C" BOOL QCALLTYPE Monitor_Wait(QCall::ObjectHandleOnStack pThis, INT32 Timeout)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
BOOL retVal = FALSE;
- OBJECTREF pThis = (OBJECTREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(pThis);
+
+ BEGIN_QCALL;
+
+ GCX_COOP();
// Arguments validated on managed side
- _ASSERTE(pThis != NULL);
+ _ASSERTE(pThis.Get() != NULL);
_ASSERTE(Timeout >= INFINITE_TIMEOUT);
- retVal = pThis->Wait(Timeout);
+ retVal = pThis.Get()->Wait(Timeout);
- HELPER_METHOD_FRAME_END();
- FC_RETURN_BOOL(retVal);
+ END_QCALL;
+
+ return retVal;
}
-FCIMPLEND
-FCIMPL1(void, ObjectNative::Pulse, Object* pThisUNSAFE)
+extern "C" void QCALLTYPE Monitor_Pulse(QCall::ObjectHandleOnStack pThis)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
- OBJECTREF pThis = (OBJECTREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pThis);
+ BEGIN_QCALL;
- if (pThis == NULL)
- COMPlusThrow(kNullReferenceException, W("NullReference_This"));
+ GCX_COOP();
- pThis->Pulse();
+ _ASSERTE(pThis.Get() != NULL);
+ pThis.Get()->Pulse();
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
}
-FCIMPLEND
-FCIMPL1(void, ObjectNative::PulseAll, Object* pThisUNSAFE)
+extern "C" void QCALLTYPE Monitor_PulseAll(QCall::ObjectHandleOnStack pThis)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
- OBJECTREF pThis = (OBJECTREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pThis);
+ BEGIN_QCALL;
- if (pThis == NULL)
- COMPlusThrow(kNullReferenceException, W("NullReference_This"));
+ GCX_COOP();
- pThis->PulseAll();
+ _ASSERTE(pThis.Get() != NULL);
+ pThis.Get()->PulseAll();
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
}
-FCIMPLEND
FCIMPL1(FC_BOOL_RET, ObjectNative::IsLockHeld, Object* pThisUNSAFE)
{
@@ -362,7 +314,7 @@ FCIMPL1(FC_BOOL_RET, ObjectNative::IsLockHeld, Object* pThisUNSAFE)
}
FCIMPLEND
-extern "C" INT64 QCALLTYPE ObjectNative_GetMonitorLockContentionCount()
+extern "C" INT64 QCALLTYPE Monitor_GetLockContentionCount()
{
QCALL_CONTRACT;
diff --git a/src/coreclr/classlibnative/bcltype/objectnative.h b/src/coreclr/classlibnative/bcltype/objectnative.h
index 819469a983458..d8948922dd0b7 100644
--- a/src/coreclr/classlibnative/bcltype/objectnative.h
+++ b/src/coreclr/classlibnative/bcltype/objectnative.h
@@ -25,20 +25,17 @@ class ObjectNative
{
public:
- // This method will return a Class object for the object
- // iff the Class object has already been created.
- // If the Class object doesn't exist then you must call the GetClass() method.
- static FCDECL1(Object*, GetObjectValue, Object* vThisRef);
static FCDECL1(INT32, GetHashCode, Object* vThisRef);
static FCDECL1(INT32, TryGetHashCode, Object* vThisRef);
static FCDECL2(FC_BOOL_RET, Equals, Object *pThisRef, Object *pCompareRef);
static FCDECL1(Object*, AllocateUninitializedClone, Object* pObjUNSAFE);
static FCDECL1(Object*, GetClass, Object* pThis);
- static FCDECL2(FC_BOOL_RET, WaitTimeout, INT32 Timeout, Object* pThisUNSAFE);
- static FCDECL1(void, Pulse, Object* pThisUNSAFE);
- static FCDECL1(void, PulseAll, Object* pThisUNSAFE);
static FCDECL1(FC_BOOL_RET, IsLockHeld, Object* pThisUNSAFE);
};
-extern "C" INT64 QCALLTYPE ObjectNative_GetMonitorLockContentionCount();
+extern "C" BOOL QCALLTYPE Monitor_Wait(QCall::ObjectHandleOnStack pThis, INT32 Timeout);
+extern "C" void QCALLTYPE Monitor_Pulse(QCall::ObjectHandleOnStack pThis);
+extern "C" void QCALLTYPE Monitor_PulseAll(QCall::ObjectHandleOnStack pThis);
+extern "C" INT64 QCALLTYPE Monitor_GetLockContentionCount();
+
#endif // _OBJECTNATIVE_H_
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml
index 2b853993311eb..6624968f544b6 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml
@@ -929,10 +929,6 @@
CP0002
M:System.TypedReference.get_IsNull
-
- CP0014
- M:System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(System.Object)->object?:[T:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute]
-
CP0015
M:System.Diagnostics.Tracing.EventSource.Write``1(System.String,``0):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute]
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 7895376c608ec..3342337435419 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
@@ -58,7 +58,8 @@ public static void RunModuleConstructor(ModuleHandle module)
// Nothing to do for the native AOT. All module cctors execute eagerly.
}
- public static object GetObjectValue(object? obj)
+ [return: NotNullIfNotNull(nameof(obj))]
+ public static object? GetObjectValue(object? obj)
{
if (obj == null)
return null;
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs
index a3c5c5d9e1884..44903db0e1521 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs
@@ -15,13 +15,10 @@ namespace System.Runtime.InteropServices
{
public static partial class Marshal
{
- internal static int SizeOfHelper(Type t, bool throwIfNotMarshalable)
+ internal static int SizeOfHelper(RuntimeType t, bool throwIfNotMarshalable)
{
Debug.Assert(throwIfNotMarshalable);
- if (t is not RuntimeType)
- throw new ArgumentException(SR.Argument_MustBeRuntimeType);
-
if (t.IsPointer /* or IsFunctionPointer */)
return IntPtr.Size;
@@ -54,9 +51,6 @@ public static IntPtr OffsetOf(Type t, string fieldName)
private static void PtrToStructureHelper(IntPtr ptr, object structure, bool allowValueClasses)
{
- ArgumentNullException.ThrowIfNull(ptr);
- ArgumentNullException.ThrowIfNull(structure);
-
if (!allowValueClasses && structure.GetEETypePtr().IsValueType)
{
throw new ArgumentException(SR.Argument_StructMustNotBeValueClass, nameof(structure));
@@ -106,12 +100,12 @@ internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
public static unsafe void DestroyStructure(IntPtr ptr, Type structuretype)
{
ArgumentNullException.ThrowIfNull(ptr);
- ArgumentNullException.ThrowIfNull(structuretype, "structureType");
+ ArgumentNullException.ThrowIfNull(structuretype, nameof(structuretype));
RuntimeTypeHandle structureTypeHandle = structuretype.TypeHandle;
- if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
- throw new ArgumentException(SR.Argument_NeedNonGenericType, "structure");
+ if (structureTypeHandle.IsGenericType())
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structuretype));
if (structureTypeHandle.IsEnum() ||
structureTypeHandle.IsInterface() ||
@@ -143,14 +137,9 @@ public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDel
ArgumentNullException.ThrowIfNull(structure);
ArgumentNullException.ThrowIfNull(ptr);
- if (fDeleteOld)
- {
- DestroyStructure(ptr, structure.GetType());
- }
-
RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;
- if (structureTypeHandle.IsGenericType() || structureTypeHandle.IsGenericTypeDefinition())
+ if (structureTypeHandle.IsGenericType())
{
throw new ArgumentException(SR.Argument_NeedNonGenericObject, nameof(structure));
}
@@ -168,6 +157,11 @@ public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDel
marshalStub = RuntimeInteropData.GetStructMarshalStub(structureTypeHandle);
}
+ if (fDeleteOld)
+ {
+ DestroyStructure(ptr, structure.GetType());
+ }
+
if (marshalStub != IntPtr.Zero)
{
if (structureTypeHandle.IsValueType())
diff --git a/src/coreclr/vm/binder.cpp b/src/coreclr/vm/binder.cpp
index 23b14a34ee43b..3415ba3a2336a 100644
--- a/src/coreclr/vm/binder.cpp
+++ b/src/coreclr/vm/binder.cpp
@@ -1122,8 +1122,6 @@ void CoreLibBinder::CheckExtended()
#define ASMCONSTANTS_RUNTIME_ASSERT(cond) _ASSERTE(cond)
#include "asmconstants.h"
- _ASSERTE(sizeof(VARIANT) == CoreLibBinder::GetClass(CLASS__NATIVEVARIANT)->GetNativeSize());
-
printf("CheckExtended: completed without exception.\n");
ErrExit:
diff --git a/src/coreclr/vm/comdependenthandle.cpp b/src/coreclr/vm/comdependenthandle.cpp
index b222190810233..8f78d01b365bc 100644
--- a/src/coreclr/vm/comdependenthandle.cpp
+++ b/src/coreclr/vm/comdependenthandle.cpp
@@ -5,33 +5,40 @@
//
//
-// FCall's for the DependentHandle class
-//
-// Handle functions require cooperative mode, making these fcalls poor candidates for QCall conversion.
+// FCalls and QCalls for the DependentHandle class
//
#include "common.h"
#include "comdependenthandle.h"
-FCIMPL2(OBJECTHANDLE, DependentHandle::InternalInitialize, Object *_target, Object *_dependent)
+FCIMPL2(OBJECTHANDLE, DependentHandle::InternalAlloc, Object *target, Object *dependent)
{
FCALL_CONTRACT;
- OBJECTREF target(_target);
- OBJECTREF dependent(_dependent);
+ // Use slow path if profiler is tracking GC
+ if (CORProfilerTrackGC())
+ return NULL;
+
+ return GetAppDomain()->GetHandleStore()->CreateDependentHandle(target, dependent);
+}
+FCIMPLEND
+
+extern "C" OBJECTHANDLE QCALLTYPE DependentHandle_InternalAllocWithGCTransition(QCall::ObjectHandleOnStack target, QCall::ObjectHandleOnStack dependent)
+{
+ QCALL_CONTRACT;
+
OBJECTHANDLE result = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_NOPOLL();
+ BEGIN_QCALL;
- // Create the handle.
- result = GetAppDomain()->CreateDependentHandle(target, dependent);
+ GCX_COOP();
+ result = GetAppDomain()->CreateDependentHandle(target.Get(), dependent.Get());
- HELPER_METHOD_FRAME_END_POLL();
+ END_QCALL;
return result;
}
-FCIMPLEND
FCIMPL1(Object*, DependentHandle::InternalGetTarget, OBJECTHANDLE handle)
{
@@ -97,16 +104,31 @@ FCIMPL2(VOID, DependentHandle::InternalSetDependent, OBJECTHANDLE handle, Object
}
FCIMPLEND
-FCIMPL1(VOID, DependentHandle::InternalFree, OBJECTHANDLE handle)
+FCIMPL1(FC_BOOL_RET, DependentHandle::InternalFree, OBJECTHANDLE handle)
{
FCALL_CONTRACT;
_ASSERTE(handle != NULL);
- HELPER_METHOD_FRAME_BEGIN_0();
+ // Use slow path if profiler is tracking GC
+ if (CORProfilerTrackGC())
+ FC_RETURN_BOOL(false);
DestroyDependentHandle(handle);
-
- HELPER_METHOD_FRAME_END();
+ FC_RETURN_BOOL(true);
}
FCIMPLEND
+
+extern "C" void QCALLTYPE DependentHandle_InternalFreeWithGCTransition(OBJECTHANDLE handle)
+{
+ QCALL_CONTRACT;
+
+ _ASSERTE(handle != NULL);
+
+ BEGIN_QCALL;
+
+ GCX_COOP();
+ DestroyDependentHandle(handle);
+
+ END_QCALL;
+}
diff --git a/src/coreclr/vm/comdependenthandle.h b/src/coreclr/vm/comdependenthandle.h
index 06786e6257746..62e94161d884e 100644
--- a/src/coreclr/vm/comdependenthandle.h
+++ b/src/coreclr/vm/comdependenthandle.h
@@ -40,13 +40,16 @@
class DependentHandle
{
public:
- static FCDECL2(OBJECTHANDLE, InternalInitialize, Object *target, Object *dependent);
+ static FCDECL2(OBJECTHANDLE, InternalAlloc, Object *target, Object *dependent);
static FCDECL1(Object *, InternalGetTarget, OBJECTHANDLE handle);
static FCDECL1(Object *, InternalGetDependent, OBJECTHANDLE handle);
static FCDECL2(Object *, InternalGetTargetAndDependent, OBJECTHANDLE handle, Object **outDependent);
static FCDECL1(VOID, InternalSetTargetToNull, OBJECTHANDLE handle);
static FCDECL2(VOID, InternalSetDependent, OBJECTHANDLE handle, Object *dependent);
- static FCDECL1(VOID, InternalFree, OBJECTHANDLE handle);
+ static FCDECL1(FC_BOOL_RET, InternalFree, OBJECTHANDLE handle);
};
+extern "C" OBJECTHANDLE QCALLTYPE DependentHandle_InternalAllocWithGCTransition(QCall::ObjectHandleOnStack target, QCall::ObjectHandleOnStack dependent);
+extern "C" void QCALLTYPE DependentHandle_InternalFreeWithGCTransition(OBJECTHANDLE handle);
+
#endif
diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h
index 0dd79fb124f82..c3288e8659a6a 100644
--- a/src/coreclr/vm/corelib.h
+++ b/src/coreclr/vm/corelib.h
@@ -1068,8 +1068,7 @@ DEFINE_METHOD(HANDLE_MARSHALER, CONVERT_SAFEHANDLE_TO_NATIVE,ConvertSaf
DEFINE_METHOD(HANDLE_MARSHALER, THROW_SAFEHANDLE_FIELD_CHANGED, ThrowSafeHandleFieldChanged, SM_RetVoid)
DEFINE_METHOD(HANDLE_MARSHALER, THROW_CRITICALHANDLE_FIELD_CHANGED, ThrowCriticalHandleFieldChanged, SM_RetVoid)
-DEFINE_CLASS(NATIVEVARIANT, StubHelpers, NativeVariant)
-DEFINE_CLASS(NATIVEDECIMAL, StubHelpers, NativeDecimal)
+DEFINE_CLASS(COMVARIANT, Marshalling, ComVariant)
DEFINE_CLASS(SZARRAYHELPER, System, SZArrayHelper)
// Note: The order of methods here has to match order they are implemented on the interfaces in
diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h
index 227fcecbbc814..79e094023188f 100644
--- a/src/coreclr/vm/ecalllist.h
+++ b/src/coreclr/vm/ecalllist.h
@@ -45,7 +45,7 @@
//
FCFuncStart(gDependentHandleFuncs)
- FCFuncElement("InternalInitialize", DependentHandle::InternalInitialize)
+ FCFuncElement("InternalAlloc", DependentHandle::InternalAlloc)
FCFuncElement("InternalGetTarget", DependentHandle::InternalGetTarget)
FCFuncElement("InternalGetDependent", DependentHandle::InternalGetDependent)
FCFuncElement("InternalGetTargetAndDependent", DependentHandle::InternalGetTargetAndDependent)
@@ -469,10 +469,6 @@ FCFuncEnd()
FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("GetLastPInvokeError", MarshalNative::GetLastPInvokeError)
FCFuncElement("SetLastPInvokeError", MarshalNative::SetLastPInvokeError)
- FCFuncElement("SizeOfHelper", MarshalNative::SizeOfClass)
- FCFuncElement("StructureToPtr", MarshalNative::StructureToPtr)
- FCFuncElement("PtrToStructureHelper", MarshalNative::PtrToStructureHelper)
- FCFuncElement("DestroyStructure", MarshalNative::DestroyStructure)
FCFuncElement("GetExceptionCode", ExceptionNative::GetExceptionCode)
FCFuncElement("GetExceptionPointers", ExceptionNative::GetExceptionPointers)
@@ -518,14 +514,10 @@ FCFuncStart(gMonitorFuncs)
FCFuncElement("ReliableEnter", JIT_MonReliableEnter)
FCFuncElement("ReliableEnterTimeout", JIT_MonTryEnter)
FCFuncElement("Exit", JIT_MonExit)
- FCFuncElement("ObjWait", ObjectNative::WaitTimeout)
- FCFuncElement("ObjPulse", ObjectNative::Pulse)
- FCFuncElement("ObjPulseAll", ObjectNative::PulseAll)
FCFuncElement("IsEnteredNative", ObjectNative::IsLockHeld)
FCFuncEnd()
FCFuncStart(gRuntimeHelpers)
- FCFuncElement("GetObjectValue", ObjectNative::GetObjectValue)
FCFuncElement("InitializeArray", ArrayNative::InitializeArray)
FCFuncElement("GetSpanDataFrom", ArrayNative::GetSpanDataFrom)
FCFuncElement("PrepareDelegate", ReflectionInvocation::PrepareDelegate)
@@ -564,11 +556,6 @@ FCFuncStart(gMngdNativeArrayMarshalerFuncs)
FCFuncEnd()
#ifdef FEATURE_COMINTEROP
-FCFuncStart(gObjectMarshalerFuncs)
- FCFuncElement("ConvertToNative", StubHelpers::ObjectMarshaler__ConvertToNative)
- FCFuncElement("ConvertToManaged", StubHelpers::ObjectMarshaler__ConvertToManaged)
- FCFuncElement("ClearNative", StubHelpers::ObjectMarshaler__ClearNative)
-FCFuncEnd()
FCFuncStart(gInterfaceMarshalerFuncs)
FCFuncElement("ConvertToNative", StubHelpers::InterfaceMarshaler__ConvertToNative)
@@ -608,7 +595,6 @@ FCFuncStart(gStubHelperFuncs)
FCFuncElement("ProfilerBeginTransitionCallback", StubHelpers::ProfilerBeginTransitionCallback)
FCFuncElement("ProfilerEndTransitionCallback", StubHelpers::ProfilerEndTransitionCallback)
#endif
- FCFuncElement("CreateCustomMarshalerHelper", StubHelpers::CreateCustomMarshalerHelper)
FCFuncElement("FmtClassUpdateNativeInternal", StubHelpers::FmtClassUpdateNativeInternal)
FCFuncElement("FmtClassUpdateCLRInternal", StubHelpers::FmtClassUpdateCLRInternal)
FCFuncElement("LayoutDestroyNativeInternal", StubHelpers::LayoutDestroyNativeInternal)
@@ -630,8 +616,8 @@ FCFuncStart(gStubHelperFuncs)
FCFuncEnd()
FCFuncStart(gGCHandleFuncs)
- FCFuncElement("InternalAlloc", MarshalNative::GCHandleInternalAlloc)
- FCFuncElement("InternalFree", MarshalNative::GCHandleInternalFree)
+ FCFuncElement("_InternalAlloc", MarshalNative::GCHandleInternalAlloc)
+ FCFuncElement("_InternalFree", MarshalNative::GCHandleInternalFree)
FCFuncElement("InternalGet", MarshalNative::GCHandleInternalGet)
FCFuncElement("InternalSet", MarshalNative::GCHandleInternalSet)
FCFuncElement("InternalCompareExchange", MarshalNative::GCHandleInternalCompareExchange)
@@ -722,9 +708,6 @@ FCClassElement("Monitor", "System.Threading", gMonitorFuncs)
FCClassElement("OAVariantLib", "Microsoft.Win32", gOAVariantFuncs)
#endif
FCClassElement("Object", "System", gObjectFuncs)
-#ifdef FEATURE_COMINTEROP
-FCClassElement("ObjectMarshaler", "System.StubHelpers", gObjectMarshalerFuncs)
-#endif
FCClassElement("RuntimeAssembly", "System.Reflection", gRuntimeAssemblyFuncs)
FCClassElement("RuntimeFieldHandle", "System", gCOMFieldHandleNewFuncs)
diff --git a/src/coreclr/vm/fieldmarshaler.cpp b/src/coreclr/vm/fieldmarshaler.cpp
index ae92fd97c2cd4..57fc5b82bad14 100644
--- a/src/coreclr/vm/fieldmarshaler.cpp
+++ b/src/coreclr/vm/fieldmarshaler.cpp
@@ -127,9 +127,7 @@ VOID ParseNativeType(Module* pModule,
*pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__CURRENCY));
break;
case MarshalInfo::MARSHAL_TYPE_DECIMAL:
- // The decimal type can't be blittable since the managed and native alignment requirements differ.
- // Native needs 8-byte alignment since one field is a 64-bit integer, but managed only needs 4-byte alignment since all fields are ints.
- *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__NATIVEDECIMAL));
+ *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__DECIMAL));
break;
case MarshalInfo::MARSHAL_TYPE_GUID:
*pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__GUID));
@@ -163,7 +161,7 @@ VOID ParseNativeType(Module* pModule,
break;
#ifdef FEATURE_COMINTEROP
case MarshalInfo::MARSHAL_TYPE_OBJECT:
- *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__NATIVEVARIANT));
+ *pNFD = NativeFieldDescriptor(pFD, CoreLibBinder::GetClass(CLASS__COMVARIANT));
break;
#endif
case MarshalInfo::MARSHAL_TYPE_SAFEHANDLE:
diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp
index 431064f4e121d..1c87acac73685 100644
--- a/src/coreclr/vm/ilmarshalers.cpp
+++ b/src/coreclr/vm/ilmarshalers.cpp
@@ -1138,7 +1138,7 @@ LocalDesc ILObjectMarshaler::GetNativeType()
{
STANDARD_VM_CONTRACT;
- return LocalDesc(TypeHandle(CoreLibBinder::GetClass(CLASS__NATIVEVARIANT)));
+ return LocalDesc(TypeHandle(CoreLibBinder::GetClass(CLASS__COMVARIANT)));
}
LocalDesc ILObjectMarshaler::GetManagedType()
diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp
index ebe3fdf64f0d3..5a57cb888e7fe 100644
--- a/src/coreclr/vm/marshalnative.cpp
+++ b/src/coreclr/vm/marshalnative.cpp
@@ -91,190 +91,74 @@ extern "C" BOOL QCALLTYPE MarshalNative_IsBuiltInComSupported()
return ret;
}
-FCIMPL3(VOID, MarshalNative::StructureToPtr, Object* pObjUNSAFE, LPVOID ptr, CLR_BOOL fDeleteOld)
+extern "C" BOOL QCALLTYPE MarshalNative_TryGetStructMarshalStub(void* enregisteredTypeHandle, PCODE* pStructMarshalStub, SIZE_T* pSize)
{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(ptr, NULL_OK));
- }
- CONTRACTL_END;
-
- OBJECTREF pObj = (OBJECTREF) pObjUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_1(pObj);
-
- if (ptr == NULL)
- COMPlusThrowArgumentNull(W("ptr"));
- if (pObj == NULL)
- COMPlusThrowArgumentNull(W("structure"));
-
- // Code path will accept both regular layout objects and boxed value classes
- // with layout.
-
- MethodTable *pMT = pObj->GetMethodTable();
-
- if (pMT->HasInstantiation())
- COMPlusThrowArgumentException(W("structure"), W("Argument_NeedNonGenericObject"));
-
- if (pMT->IsBlittable())
- {
- memcpyNoGCRefs(ptr, pObj->GetData(), pMT->GetNativeSize());
- }
- else if (pMT->HasLayout())
- {
- EEMarshalingData* pEEMarshalingData = pMT->GetLoaderAllocator()->GetMarshalingDataIfAvailable();
- MethodDesc* structMarshalStub = (pEEMarshalingData != NULL) ? pEEMarshalingData->LookupStructILStubSpeculative(pMT) : NULL;
-
- if (structMarshalStub == NULL)
- {
- GCX_PREEMP();
- structMarshalStub = NDirect::CreateStructMarshalILStub(pMT);
- }
-
- if (fDeleteOld)
- {
- MarshalStructViaILStub(structMarshalStub, pObj->GetData(), ptr, StructMarshalStubs::MarshalOperation::Cleanup);
- }
-
- MarshalStructViaILStub(structMarshalStub, pObj->GetData(), ptr, StructMarshalStubs::MarshalOperation::Marshal);
- }
- else
- {
- COMPlusThrowArgumentException(W("structure"), W("Argument_MustHaveLayoutOrBeBlittable"));
- }
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL3(VOID, MarshalNative::PtrToStructureHelper, LPVOID ptr, Object* pObjIn, CLR_BOOL allowValueClasses)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(ptr, NULL_OK));
- }
- CONTRACTL_END;
-
- OBJECTREF pObj = ObjectToOBJECTREF(pObjIn);
-
- HELPER_METHOD_FRAME_BEGIN_1(pObj);
-
- if (ptr == NULL)
- COMPlusThrowArgumentNull(W("ptr"));
- if (pObj == NULL)
- COMPlusThrowArgumentNull(W("structure"));
-
- // Code path will accept regular layout objects.
- MethodTable *pMT = pObj->GetMethodTable();
-
- // Validate that the object passed in is not a value class.
- if (!allowValueClasses && pMT->IsValueType())
- {
- COMPlusThrowArgumentException(W("structure"), W("Argument_StructMustNotBeValueClass"));
- }
- else if (pMT->IsBlittable())
- {
- memcpyNoGCRefs(pObj->GetData(), ptr, pMT->GetNativeSize());
- }
- else if (pMT->HasLayout())
- {
- EEMarshalingData* pEEMarshalingData = pMT->GetLoaderAllocator()->GetMarshalingDataIfAvailable();
- MethodDesc* structMarshalStub = (pEEMarshalingData != NULL) ? pEEMarshalingData->LookupStructILStubSpeculative(pMT) : NULL;
-
- if (structMarshalStub == NULL)
- {
- GCX_PREEMP();
- structMarshalStub = NDirect::CreateStructMarshalILStub(pMT);
- }
-
- MarshalStructViaILStub(structMarshalStub, pObj->GetData(), ptr, StructMarshalStubs::MarshalOperation::Unmarshal);
- }
- else
- {
- COMPlusThrowArgumentException(W("structure"), W("Argument_MustHaveLayoutOrBeBlittable"));
- }
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-FCIMPL2(VOID, MarshalNative::DestroyStructure, LPVOID ptr, ReflectClassBaseObject* refClassUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(ptr, NULL_OK));
- }
- CONTRACTL_END;
+ QCALL_CONTRACT;
- REFLECTCLASSBASEREF refClass = (REFLECTCLASSBASEREF) refClassUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(refClass);
+ BOOL ret = FALSE;
- if (ptr == NULL)
- COMPlusThrowArgumentNull(W("ptr"));
- if (refClass == NULL)
- COMPlusThrowArgumentNull(W("structureType"));
- if (refClass->GetMethodTable() != g_pRuntimeTypeClass)
- COMPlusThrowArgumentException(W("structureType"), W("Argument_MustBeRuntimeType"));
+ BEGIN_QCALL;
- TypeHandle th = refClass->GetType();
-
- if (th.HasInstantiation())
- COMPlusThrowArgumentException(W("structureType"), W("Argument_NeedNonGenericType"));
+ TypeHandle th = TypeHandle::FromPtr(enregisteredTypeHandle);
if (th.IsBlittable())
{
- // ok to call with blittable structure, but no work to do in this case.
+ *pStructMarshalStub = NULL;
+ *pSize = th.GetMethodTable()->GetNativeSize();
+ ret = TRUE;
}
else if (th.HasLayout())
{
MethodTable* pMT = th.GetMethodTable();
+ MethodDesc* structMarshalStub = NULL;
+
EEMarshalingData* pEEMarshalingData = pMT->GetLoaderAllocator()->GetMarshalingDataIfAvailable();
- MethodDesc* structMarshalStub = (pEEMarshalingData != NULL) ? pEEMarshalingData->LookupStructILStubSpeculative(pMT) : NULL;
+ if (pEEMarshalingData != NULL)
+ {
+ GCX_COOP();
+ structMarshalStub = pEEMarshalingData->LookupStructILStubSpeculative(pMT);
+ }
if (structMarshalStub == NULL)
{
- GCX_PREEMP();
structMarshalStub = NDirect::CreateStructMarshalILStub(pMT);
}
- MarshalStructViaILStub(structMarshalStub, nullptr, ptr, StructMarshalStubs::MarshalOperation::Cleanup);
+ *pStructMarshalStub = structMarshalStub->GetSingleCallableAddrOfCode();
+ *pSize = 0;
+ ret = TRUE;
}
else
{
- COMPlusThrowArgumentException(W("structureType"), W("Argument_MustHaveLayoutOrBeBlittable"));
+ *pStructMarshalStub = NULL;
+ *pSize = 0;
}
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
+
+ return ret;
}
-FCIMPLEND
/************************************************************************
* PInvoke.SizeOf(Class)
*/
-FCIMPL2(UINT32, MarshalNative::SizeOfClass, ReflectClassBaseObject* refClassUNSAFE, CLR_BOOL throwIfNotMarshalable)
+extern "C" INT32 QCALLTYPE MarshalNative_SizeOfHelper(QCall::TypeHandle t, BOOL throwIfNotMarshalable)
{
CONTRACTL
{
- FCALL_CHECK;
- PRECONDITION(CheckPointer(refClassUNSAFE));
+ QCALL_CHECK;
}
CONTRACTL_END;
- UINT32 rv = 0;
- REFLECTCLASSBASEREF refClass = (REFLECTCLASSBASEREF)refClassUNSAFE;
+ INT32 rv = 0;
- HELPER_METHOD_FRAME_BEGIN_RET_1(refClass);
+ BEGIN_QCALL;
// refClass is validated to be non-NULL RuntimeType by callers
- TypeHandle th = refClass->GetType();
+ TypeHandle th = t.AsTypeHandle();
if (throwIfNotMarshalable && (!th.IsBlittable() || th.IsArray()))
{
- GCX_PREEMP();
// Determine if the type is marshalable
if (!IsStructMarshalable(th))
{
@@ -287,10 +171,10 @@ FCIMPL2(UINT32, MarshalNative::SizeOfClass, ReflectClassBaseObject* refClassUNSA
// The type is marshalable or we don't care so return its size.
rv = th.GetMethodTable()->GetNativeSize();
- HELPER_METHOD_FRAME_END();
+
+ END_QCALL;
return rv;
}
-FCIMPLEND
/************************************************************************
@@ -450,18 +334,18 @@ FCIMPLEND
* Support for the GCHandle class.
*/
-NOINLINE static OBJECTHANDLE FCDiagCreateHandle(OBJECTREF objRef, int type)
+extern "C" OBJECTHANDLE QCALLTYPE GCHandle_InternalAllocWithGCTransition(QCall::ObjectHandleOnStack obj, int type)
{
+ QCALL_CONTRACT;
+
OBJECTHANDLE hnd = NULL;
- FC_INNER_PROLOG(MarshalNative::GCHandleInternalAlloc);
+ BEGIN_QCALL;
- // Make the stack walkable for the profiler
- HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_NOPOLL(Frame::FRAME_ATTR_EXACT_DEPTH | Frame::FRAME_ATTR_CAPTURE_DEPTH_2);
- hnd = GetAppDomain()->CreateTypedHandle(objRef, static_cast(type));
- HELPER_METHOD_FRAME_END_POLL();
+ GCX_COOP();
+ hnd = GetAppDomain()->CreateTypedHandle(obj.Get(), static_cast(type));
- FC_INNER_EPILOG();
+ END_QCALL;
return hnd;
}
@@ -470,47 +354,39 @@ FCIMPL2(LPVOID, MarshalNative::GCHandleInternalAlloc, Object *obj, int type)
{
FCALL_CONTRACT;
- OBJECTREF objRef(obj);
-
assert(type >= HNDTYPE_WEAK_SHORT && type <= HNDTYPE_SIZEDREF);
if (CORProfilerTrackGC())
- {
- FC_INNER_RETURN(LPVOID, (LPVOID) FCDiagCreateHandle(objRef, type));
- }
+ return NULL;
- OBJECTHANDLE hnd = GetAppDomain()->GetHandleStore()->CreateHandleOfType(OBJECTREFToObject(objRef), static_cast(type));
- if (!hnd)
- {
- FCThrow(kOutOfMemoryException);
- }
- return (LPVOID) hnd;
+ return GetAppDomain()->GetHandleStore()->CreateHandleOfType(obj, static_cast(type));
}
FCIMPLEND
-NOINLINE static void FCDiagDestroyHandle(OBJECTHANDLE handle)
+extern "C" void QCALLTYPE GCHandle_InternalFreeWithGCTransition(OBJECTHANDLE handle)
{
- FC_INNER_PROLOG(MarshalNative::GCHandleInternalFree);
+ QCALL_CONTRACT;
+
+ _ASSERTE(handle != NULL);
- // Make the stack walkable for the profiler
- HELPER_METHOD_FRAME_BEGIN_ATTRIB(Frame::FRAME_ATTR_EXACT_DEPTH | Frame::FRAME_ATTR_CAPTURE_DEPTH_2);
+ BEGIN_QCALL;
+
+ GCX_COOP();
DestroyTypedHandle(handle);
- HELPER_METHOD_FRAME_END();
- FC_INNER_EPILOG();
+ END_QCALL;
}
// Free a GC handle.
-FCIMPL1(VOID, MarshalNative::GCHandleInternalFree, OBJECTHANDLE handle)
+FCIMPL1(FC_BOOL_RET, MarshalNative::GCHandleInternalFree, OBJECTHANDLE handle)
{
FCALL_CONTRACT;
if (CORProfilerTrackGC())
- {
- FC_INNER_RETURN_VOID(FCDiagDestroyHandle(handle));
- }
+ FC_RETURN_BOOL(false);
GCHandleUtilities::GetGCHandleManager()->DestroyHandleOfUnknownType(handle);
+ FC_RETURN_BOOL(true);
}
FCIMPLEND
diff --git a/src/coreclr/vm/marshalnative.h b/src/coreclr/vm/marshalnative.h
index 28c4b6b0de22a..a2524b8525f1c 100644
--- a/src/coreclr/vm/marshalnative.h
+++ b/src/coreclr/vm/marshalnative.h
@@ -14,8 +14,6 @@
#include "fcall.h"
-#define MAX_UTF8_CHAR_SIZE 3
-
class MarshalNative
{
public:
@@ -28,18 +26,12 @@ class MarshalNative
static FCDECL1(int, GetHRForException, Object* eUNSAFE);
#endif // FEATURE_COMINTEROP
- static FCDECL2(UINT32, SizeOfClass, ReflectClassBaseObject* refClass, CLR_BOOL throwIfNotMarshalable);
-
static FCDECL1(UINT32, OffsetOfHelper, ReflectFieldObject* pFieldUNSAFE);
static FCDECL0(int, GetLastPInvokeError);
static FCDECL1(void, SetLastPInvokeError, int error);
- static FCDECL3(VOID, StructureToPtr, Object* pObjUNSAFE, LPVOID ptr, CLR_BOOL fDeleteOld);
- static FCDECL3(VOID, PtrToStructureHelper, LPVOID ptr, Object* pObjIn, CLR_BOOL allowValueClasses);
- static FCDECL2(VOID, DestroyStructure, LPVOID ptr, ReflectClassBaseObject* refClassUNSAFE);
-
static FCDECL2(LPVOID, GCHandleInternalAlloc, Object *obj, int type);
- static FCDECL1(VOID, GCHandleInternalFree, OBJECTHANDLE handle);
+ static FCDECL1(FC_BOOL_RET, GCHandleInternalFree, OBJECTHANDLE handle);
static FCDECL1(LPVOID, GCHandleInternalGet, OBJECTHANDLE handle);
static FCDECL2(VOID, GCHandleInternalSet, OBJECTHANDLE handle, Object *obj);
static FCDECL3(Object*, GCHandleInternalCompareExchange, OBJECTHANDLE handle, Object *obj, Object* oldObj);
@@ -58,6 +50,12 @@ class MarshalNative
extern "C" VOID QCALLTYPE MarshalNative_Prelink(MethodDesc * pMD);
extern "C" BOOL QCALLTYPE MarshalNative_IsBuiltInComSupported();
+extern "C" BOOL QCALLTYPE MarshalNative_TryGetStructMarshalStub(void* enregisteredTypeHandle, PCODE* pStructMarshalStub, SIZE_T* pSize);
+extern "C" INT32 QCALLTYPE MarshalNative_SizeOfHelper(QCall::TypeHandle t, BOOL throwIfNotMarshalable);
+
+extern "C" OBJECTHANDLE QCALLTYPE GCHandle_InternalAllocWithGCTransition(QCall::ObjectHandleOnStack obj, int type);
+extern "C" void QCALLTYPE GCHandle_InternalFreeWithGCTransition(OBJECTHANDLE handle);
+
#ifdef _DEBUG
using IsInCooperativeGCMode_fn = BOOL(STDMETHODCALLTYPE*)(void);
extern "C" IsInCooperativeGCMode_fn QCALLTYPE MarshalNative_GetIsInCooperativeGCModeFunctionPointer();
diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp
index 8e50860a73bff..4c63edb027f30 100644
--- a/src/coreclr/vm/mlinfo.cpp
+++ b/src/coreclr/vm/mlinfo.cpp
@@ -391,9 +391,7 @@ CustomMarshalerHelper *SetupCustomMarshalerHelper(LPCUTF8 strMarshalerTypeName,
{
CONTRACT (CustomMarshalerHelper*)
{
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
+ STANDARD_VM_CHECK;
PRECONDITION(CheckPointer(pAssembly));
POSTCONDITION(CheckPointer(RETVAL));
}
@@ -4057,21 +4055,18 @@ bool IsUnsupportedTypedrefReturn(MetaSig& msig)
#include "stubhelpers.h"
-FCIMPL3(void*, StubHelpers::CreateCustomMarshalerHelper,
- MethodDesc* pMD,
- mdToken paramToken,
- TypeHandle hndManagedType)
+
+extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
CustomMarshalerHelper* pCMHelper = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_0();
+ BEGIN_QCALL;
Module* pModule = pMD->GetModule();
Assembly* pAssembly = pModule->GetAssembly();
-
#ifdef FEATURE_COMINTEROP
if (!hndManagedType.IsTypeDesc() &&
IsTypeRefOrDef(g_CollectionsEnumeratorClassName, hndManagedType.GetModule(), hndManagedType.GetCl()))
@@ -4108,9 +4103,8 @@ FCIMPL3(void*, StubHelpers::CreateCustomMarshalerHelper,
hndManagedType);
}
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
return (void*)pCMHelper;
}
-FCIMPLEND
diff --git a/src/coreclr/vm/namespace.h b/src/coreclr/vm/namespace.h
index 8b51f9ca62391..42389240d6f0d 100644
--- a/src/coreclr/vm/namespace.h
+++ b/src/coreclr/vm/namespace.h
@@ -20,9 +20,7 @@
#define g_ResourcesNS g_SystemNS ".Resources"
#define g_DiagnosticsNS g_SystemNS ".Diagnostics"
#define g_CodeContractsNS g_DiagnosticsNS ".Contracts"
-#define g_AssembliesNS g_SystemNS ".Configuration.Assemblies"
#define g_GlobalizationNS g_SystemNS ".Globalization"
-#define g_IsolatedStorageNS g_SystemNS ".IO.IsolatedStorage"
#define g_TextNS g_SystemNS ".Text"
#define g_CollectionsGenericNS g_SystemNS ".Collections.Generic"
@@ -43,22 +41,8 @@
#define g_ConstrainedExecutionNS g_RuntimeNS ".ConstrainedExecution"
#define g_SecurityNS g_SystemNS ".Security"
-#define g_UtilNS g_SecurityNS ".Util"
-#define g_PublicKeyNS g_SecurityNS ".PublicKey"
-#define g_PermissionsNS g_SecurityNS ".Permissions"
-#define g_PrincipalNS g_SecurityNS ".Principal"
-#define g_PolicyNS g_SecurityNS ".Policy"
#define g_CryptographyNS g_SecurityNS ".Cryptography"
-#define g_X509NS g_CryptographyNS ".X509Certificates"
-
#define g_SerializationNS g_RuntimeNS ".Serialization"
-#define g_RemotingNS g_RuntimeNS ".Remoting"
-#define g_ActivationNS g_RemotingNS ".Activation"
-#define g_ProxiesNS g_RemotingNS ".Proxies"
-#define g_ContextsNS g_RemotingNS ".Contexts"
-#define g_MessagingNS g_RemotingNS ".Messaging"
-#define g_RemotingServicesNS g_RemotingNS ".Services"
-#define g_LifetimeNS g_RemotingNS ".Lifetime"
#define g_MicrosoftNS "Microsoft"
diff --git a/src/coreclr/vm/olevariant.cpp b/src/coreclr/vm/olevariant.cpp
index e4d9174dc3edc..888ebdd380dae 100644
--- a/src/coreclr/vm/olevariant.cpp
+++ b/src/coreclr/vm/olevariant.cpp
@@ -835,7 +835,7 @@ MethodTable* OleVariant::GetNativeMethodTableForVarType(VARTYPE vt, MethodTable*
case VT_CARRAY:
return CoreLibBinder::GetClass(CLASS__INTPTR);
case VT_VARIANT:
- return CoreLibBinder::GetClass(CLASS__NATIVEVARIANT);
+ return CoreLibBinder::GetClass(CLASS__COMVARIANT);
case VTHACK_ANSICHAR:
return CoreLibBinder::GetClass(CLASS__BYTE);
case VT_UI2:
@@ -845,7 +845,7 @@ MethodTable* OleVariant::GetNativeMethodTableForVarType(VARTYPE vt, MethodTable*
// MethodTable to ensure the correct size.
return CoreLibBinder::GetClass(CLASS__UINT16);
case VT_DECIMAL:
- return CoreLibBinder::GetClass(CLASS__NATIVEDECIMAL);
+ return CoreLibBinder::GetClass(CLASS__DECIMAL);
default:
PREFIX_ASSUME(pManagedMT != NULL);
return pManagedMT;
@@ -1154,15 +1154,6 @@ void VariantData::NewVariant(VariantData * const& dest, const CVTypes type, INT6
}
}
-void SafeVariantClearHelper(_Inout_ VARIANT* pVar)
-{
- WRAPPER_NO_CONTRACT;
-
- VariantClear(pVar);
-}
-
-class OutOfMemoryException;
-
void SafeVariantClear(VARIANT* pVar)
{
CONTRACTL
@@ -1176,52 +1167,19 @@ void SafeVariantClear(VARIANT* pVar)
if (pVar)
{
GCX_PREEMP();
- SCAN_EHMARKER();
- PAL_CPP_TRY
- {
- // These are holders to tell the contract system that we're catching all exceptions.
- SCAN_EHMARKER_TRY();
- CLR_TRY_MARKER();
-
- // Most of time, oleaut32.dll is loaded already when we get here.
- // Sometimes, CLR initializes Variant without loading oleaut32.dll, e.g. VT_BOOL.
- // It is better for performance with EX_TRY than
-
- SafeVariantClearHelper(pVar);
-
- SCAN_EHMARKER_END_TRY();
- }
-#pragma warning(suppress: 4101)
- PAL_CPP_CATCH_DERIVED(OutOfMemoryException, obj)
- {
- SCAN_EHMARKER_CATCH();
-
-#if defined(STACK_GUARDS_DEBUG)
- // Catching and just swallowing an exception means we need to tell
- // the SO code that it should go back to normal operation, as it
- // currently thinks that the exception is still on the fly.
- GetThread()->GetCurrentStackGuard()->RestoreCurrentGuard();
-#endif
-
- SCAN_EHMARKER_END_CATCH();
- }
- PAL_CPP_ENDTRY;
+ VariantClear(pVar);
- FillMemory(pVar, sizeof(VARIANT), 0x00);
+ // VariantClear resets the instance to VT_EMPTY (0)
+ // COMPAT: Clear the remaining memory for compat. The instance remains set to VT_EMPTY (0).
+ ZeroMemory(pVar, sizeof(VARIANT));
}
}
-FORCEINLINE void EmptyVariant(VARIANT* value)
-{
- WRAPPER_NO_CONTRACT;
- SafeVariantClear(value);
-}
-
-class VariantEmptyHolder : public Wrapper, EmptyVariant, NULL>
+class VariantEmptyHolder : public Wrapper, SafeVariantClear, NULL>
{
public:
VariantEmptyHolder(VARIANT* p = NULL) :
- Wrapper, EmptyVariant, NULL>(p)
+ Wrapper, SafeVariantClear, NULL>(p)
{
WRAPPER_NO_CONTRACT;
}
@@ -1230,7 +1188,7 @@ class VariantEmptyHolder : public Wrapper, Empty
{
WRAPPER_NO_CONTRACT;
- Wrapper, EmptyVariant, NULL>::operator=(p);
+ Wrapper, SafeVariantClear, NULL>::operator=(p);
}
};
diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp
index 943ec19bcc2ad..7400c9d535a1a 100644
--- a/src/coreclr/vm/qcallentrypoints.cpp
+++ b/src/coreclr/vm/qcallentrypoints.cpp
@@ -212,6 +212,8 @@ static const Entry s_QCall[] =
DllImportEntry(ClrConfig_GetConfigBoolValue)
DllImportEntry(Buffer_Clear)
DllImportEntry(Buffer_MemMove)
+ DllImportEntry(DependentHandle_InternalAllocWithGCTransition)
+ DllImportEntry(DependentHandle_InternalFreeWithGCTransition)
DllImportEntry(GCInterface_StartNoGCRegion)
DllImportEntry(GCInterface_EndNoGCRegion)
DllImportEntry(GCInterface_GetTotalMemory)
@@ -227,8 +229,12 @@ static const Entry s_QCall[] =
DllImportEntry(GCInterface_RefreshMemoryLimit)
DllImportEntry(GCInterface_EnableNoGCRegionCallback)
DllImportEntry(GCInterface_GetGenerationBudget)
+ DllImportEntry(GCHandle_InternalAllocWithGCTransition)
+ DllImportEntry(GCHandle_InternalFreeWithGCTransition)
DllImportEntry(MarshalNative_Prelink)
DllImportEntry(MarshalNative_IsBuiltInComSupported)
+ DllImportEntry(MarshalNative_TryGetStructMarshalStub)
+ DllImportEntry(MarshalNative_SizeOfHelper)
DllImportEntry(MarshalNative_GetHINSTANCE)
#ifdef _DEBUG
DllImportEntry(MarshalNative_GetIsInCooperativeGCModeFunctionPointer)
@@ -262,7 +268,10 @@ static const Entry s_QCall[] =
DllImportEntry(GetFileLoadExceptionMessage)
DllImportEntry(FileLoadException_GetMessageForHR)
DllImportEntry(Interlocked_MemoryBarrierProcessWide)
- DllImportEntry(ObjectNative_GetMonitorLockContentionCount)
+ DllImportEntry(Monitor_Wait)
+ DllImportEntry(Monitor_Pulse)
+ DllImportEntry(Monitor_PulseAll)
+ DllImportEntry(Monitor_GetLockContentionCount)
DllImportEntry(ReflectionInvocation_RunClassConstructor)
DllImportEntry(ReflectionInvocation_RunModuleConstructor)
DllImportEntry(ReflectionInvocation_CompileMethod)
@@ -338,7 +347,10 @@ static const Entry s_QCall[] =
#if defined(TARGET_X86) || defined(TARGET_AMD64)
DllImportEntry(X86BaseCpuId)
#endif
+ DllImportEntry(StubHelpers_CreateCustomMarshalerHelper)
#if defined(FEATURE_COMINTEROP)
+ DllImportEntry(ObjectMarshaler_ConvertToNative)
+ DllImportEntry(ObjectMarshaler_ConvertToManaged)
DllImportEntry(InterfaceMarshaler__ClearNative)
#endif
#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
diff --git a/src/coreclr/vm/stubhelpers.cpp b/src/coreclr/vm/stubhelpers.cpp
index 9988a912967cf..1e87c7c87f236 100644
--- a/src/coreclr/vm/stubhelpers.cpp
+++ b/src/coreclr/vm/stubhelpers.cpp
@@ -326,13 +326,17 @@ FCIMPLEND
#include
-FCIMPL2(void, StubHelpers::ObjectMarshaler__ConvertToNative, Object* pSrcUNSAFE, VARIANT* pDest)
+extern "C" void QCALLTYPE ObjectMarshaler_ConvertToNative(QCall::ObjectHandleOnStack pSrcUNSAFE, VARIANT* pDest)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
- OBJECTREF pSrc = ObjectToOBJECTREF(pSrcUNSAFE);
+ BEGIN_QCALL;
+
+ GCX_COOP();
+
+ OBJECTREF pSrc = pSrcUNSAFE.Get();
+ GCPROTECT_BEGIN(pSrc);
- HELPER_METHOD_FRAME_BEGIN_1(pSrc);
if (pDest->vt & VT_BYREF)
{
OleVariant::MarshalOleRefVariantForObject(&pSrc, pDest);
@@ -341,34 +345,32 @@ FCIMPL2(void, StubHelpers::ObjectMarshaler__ConvertToNative, Object* pSrcUNSAFE,
{
OleVariant::MarshalOleVariantForObject(&pSrc, pDest);
}
- HELPER_METHOD_FRAME_END();
+
+ GCPROTECT_END();
+
+ END_QCALL;
}
-FCIMPLEND
-FCIMPL1(Object*, StubHelpers::ObjectMarshaler__ConvertToManaged, VARIANT* pSrc)
+extern "C" void QCALLTYPE ObjectMarshaler_ConvertToManaged(VARIANT* pSrc, QCall::ObjectHandleOnStack retObject)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
+
+ BEGIN_QCALL;
+
+ GCX_COOP();
OBJECTREF retVal = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_1(retVal);
- // The IL stub is going to call ObjectMarshaler__ClearNative() afterwards.
+ GCPROTECT_BEGIN(retVal);
+
+ // The IL stub is going to call ObjectMarshaler.ClearNative() afterwards.
// If it doesn't it's a bug in ILObjectMarshaler.
OleVariant::MarshalObjectForOleVariant(pSrc, &retVal);
- HELPER_METHOD_FRAME_END();
+ retObject.Set(retVal);
- return OBJECTREFToObject(retVal);
-}
-FCIMPLEND
+ GCPROTECT_END();
-FCIMPL1(void, StubHelpers::ObjectMarshaler__ClearNative, VARIANT* pSrc)
-{
- FCALL_CONTRACT;
-
- HELPER_METHOD_FRAME_BEGIN_0();
- SafeVariantClear(pSrc);
- HELPER_METHOD_FRAME_END();
+ END_QCALL;
}
-FCIMPLEND
#include
FCIMPL4(IUnknown*, StubHelpers::InterfaceMarshaler__ConvertToNative, Object* pObjUNSAFE, MethodTable* pItfMT, MethodTable* pClsMT, DWORD dwFlags)
@@ -624,7 +626,7 @@ FCIMPL3(Object*, StubHelpers::GetCOMHRExceptionObject, HRESULT hr, MethodDesc *p
{
IErrorInfo *pErrInfo = NULL;
- if (pErrInfo == NULL && pMD != NULL)
+ if (pMD != NULL)
{
// Retrieve the interface method table.
MethodTable *pItfMT = ComPlusCallInfo::FromMethodDesc(pMD)->m_pInterfaceMT;
diff --git a/src/coreclr/vm/stubhelpers.h b/src/coreclr/vm/stubhelpers.h
index b9b5ea279a14a..725710b44da7b 100644
--- a/src/coreclr/vm/stubhelpers.h
+++ b/src/coreclr/vm/stubhelpers.h
@@ -45,10 +45,6 @@ class StubHelpers
#ifdef FEATURE_COMINTEROP
static FCDECL4(IUnknown*, GetCOMIPFromRCW, Object* pSrcUNSAFE, MethodDesc* pMD, void **ppTarget, CLR_BOOL* pfNeedsRelease);
- static FCDECL2(void, ObjectMarshaler__ConvertToNative, Object* pSrcUNSAFE, VARIANT* pDest);
- static FCDECL1(Object*, ObjectMarshaler__ConvertToManaged, VARIANT* pSrc);
- static FCDECL1(void, ObjectMarshaler__ClearNative, VARIANT* pSrc);
-
static FCDECL4(IUnknown*, InterfaceMarshaler__ConvertToNative, Object* pObjUNSAFE, MethodTable* pItfMT, MethodTable* pClsMT, DWORD dwFlags);
static FCDECL4(Object*, InterfaceMarshaler__ConvertToManaged, IUnknown **ppUnk, MethodTable *pItfMT, MethodTable *pClsMT, DWORD dwFlags);
static FCDECL1(Object *, InterfaceMarshaler__ConvertToManagedWithoutUnboxing, IUnknown *pNative);
@@ -65,8 +61,6 @@ class StubHelpers
static FCDECL3(Object*, GetCOMHRExceptionObject, HRESULT hr, MethodDesc *pMD, Object *unsafe_pThis);
#endif // FEATURE_COMINTEROP
- static FCDECL3(void*, CreateCustomMarshalerHelper, MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType);
-
static FCDECL3(void, FmtClassUpdateNativeInternal, Object* pObjUNSAFE, BYTE* pbNative, OBJECTREF *ppCleanupWorkListOnStack);
static FCDECL2(void, FmtClassUpdateCLRInternal, Object* pObjUNSAFE, BYTE* pbNative);
static FCDECL2(void, LayoutDestroyNativeInternal, Object* pObjUNSAFE, BYTE* pbNative);
@@ -98,7 +92,12 @@ class StubHelpers
static FCDECL0(void*, NextCallReturnAddress);
};
+extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType);
+
#ifdef FEATURE_COMINTEROP
+extern "C" void QCALLTYPE ObjectMarshaler_ConvertToNative(QCall::ObjectHandleOnStack pSrcUNSAFE, VARIANT* pDest);
+extern "C" void QCALLTYPE ObjectMarshaler_ConvertToManaged(VARIANT* pSrc, QCall::ObjectHandleOnStack retObject);
+
extern "C" void QCALLTYPE InterfaceMarshaler__ClearNative(IUnknown * pUnk);
#endif
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs
index 7a4f50bf6bcc1..7a45e868a3d02 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs
@@ -46,7 +46,7 @@ private GCHandle(object? value, GCHandleType type)
if (type == GCHandleType.Pinned)
{
// Record if the handle is pinned.
- handle = (IntPtr)((nint)handle | 1);
+ handle |= 1;
}
_handle = handle;
@@ -58,12 +58,14 @@ private GCHandle(object? value, GCHandleType type)
/// Creates a new GC handle for an object.
/// The object that the GC handle is created for.
/// A new GC handle that protects the object.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static GCHandle Alloc(object? value) => new GCHandle(value, GCHandleType.Normal);
/// Creates a new GC handle for an object.
/// The object that the GC handle is created for.
/// The type of GC handle to create.
/// A new GC handle that protects the object.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static GCHandle Alloc(object? value, GCHandleType type) => new GCHandle(value, type);
/// Frees a GC handle.
@@ -141,7 +143,7 @@ public readonly IntPtr AddrOfPinnedObject()
}
/// Determine whether this handle has been allocated or not.
- public readonly bool IsAllocated => (nint)_handle != 0;
+ public readonly bool IsAllocated => _handle != 0;
///
/// Used to create a GCHandle from an int. This is intended to
@@ -169,21 +171,21 @@ public static GCHandle FromIntPtr(IntPtr value)
/// true if the current instance is equal to the other instance; otherwise, false.
public readonly bool Equals(GCHandle other) => _handle == other._handle;
- public static bool operator ==(GCHandle a, GCHandle b) => (nint)a._handle == (nint)b._handle;
+ public static bool operator ==(GCHandle a, GCHandle b) => a._handle == b._handle;
- public static bool operator !=(GCHandle a, GCHandle b) => (nint)a._handle != (nint)b._handle;
+ public static bool operator !=(GCHandle a, GCHandle b) => a._handle != b._handle;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static IntPtr GetHandleValue(IntPtr handle) => new IntPtr((nint)handle & ~(nint)1); // Remove Pin flag
+ private static IntPtr GetHandleValue(IntPtr handle) => new IntPtr(handle & ~1); // Remove Pin flag
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static bool IsPinned(IntPtr handle) => ((nint)handle & 1) != 0; // Check Pin flag
+ private static bool IsPinned(IntPtr handle) => (handle & 1) != 0; // Check Pin flag
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ThrowIfInvalid(IntPtr handle)
{
// Check if the handle was never initialized or was freed.
- if ((nint)handle == 0)
+ if (handle == 0)
{
ThrowHelper.ThrowInvalidOperationException_HandleIsNotInitialized();
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
index 11a3319196ad9..71c6cecbc2251 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
@@ -91,14 +91,14 @@ public static int SizeOf(object structure)
{
ArgumentNullException.ThrowIfNull(structure);
- return SizeOfHelper(structure.GetType(), throwIfNotMarshalable: true);
+ return SizeOfHelper((RuntimeType)structure.GetType(), throwIfNotMarshalable: true);
}
public static int SizeOf(T structure)
{
ArgumentNullException.ThrowIfNull(structure);
- return SizeOfHelper(structure.GetType(), throwIfNotMarshalable: true);
+ return SizeOfHelper((RuntimeType)structure.GetType(), throwIfNotMarshalable: true);
}
[RequiresDynamicCode("Marshalling code for the object might not be available. Use the SizeOf overload instead.")]
@@ -107,21 +107,21 @@ public static int SizeOf(Type t)
{
ArgumentNullException.ThrowIfNull(t);
- if (t is not RuntimeType)
+ if (t is not RuntimeType rt)
{
throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
}
- if (t.IsGenericType)
+ if (rt.IsGenericType)
{
throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
}
- return SizeOfHelper(t, throwIfNotMarshalable: true);
+ return SizeOfHelper(rt, throwIfNotMarshalable: true);
}
public static int SizeOf()
{
- Type t = typeof(T);
+ RuntimeType t = (RuntimeType)typeof(T);
if (t.IsGenericType)
{
throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(T));
@@ -585,12 +585,20 @@ public static void StructureToPtr([DisallowNull] T structure, IntPtr ptr, boo
[EditorBrowsable(EditorBrowsableState.Never)]
public static void PtrToStructure(IntPtr ptr, object structure)
{
+ ArgumentNullException.ThrowIfNull(ptr);
+ ArgumentNullException.ThrowIfNull(structure);
+
PtrToStructureHelper(ptr, structure, allowValueClasses: false);
}
public static void PtrToStructure(IntPtr ptr, [DisallowNull] T structure)
{
- PtrToStructureHelper(ptr, structure, allowValueClasses: false);
+ ArgumentNullException.ThrowIfNull(ptr);
+
+ object boxedStructure = structure;
+ ArgumentNullException.ThrowIfNull(boxedStructure, nameof(structure));
+
+ PtrToStructureHelper(ptr, boxedStructure, allowValueClasses: false);
}
public static T? PtrToStructure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]T>(IntPtr ptr)
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs
index 66fa0edb4a24a..1dcf1fbdbc698 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/DestroyStructureTests.cs
@@ -64,7 +64,7 @@ public void DestroyStructure_ZeroPointer_ThrowsArgumentNullException()
[Fact]
public void DestroyStructure_NullStructureType_ThrowsArgumentNullException()
{
- AssertExtensions.Throws("structureType", () => Marshal.DestroyStructure((IntPtr)1, null));
+ AssertExtensions.Throws("structuretype", () => Marshal.DestroyStructure((IntPtr)1, null));
}
public static IEnumerable]