File: src\System\Runtime\InteropServices\GCHandle.CoreCLR.cs
Web Access
Project: src\src\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj (System.Private.CoreLib)
// 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.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)]
        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)]
        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
        [MethodImpl(MethodImplOptions.InternalCall)]
        internal static extern object? InternalGet(IntPtr handle);
#else
        internal static unsafe object? InternalGet(IntPtr handle) => *(object*)handle;
#endif
 
        [MethodImpl(MethodImplOptions.InternalCall)]
        internal static extern void InternalSet(IntPtr handle, object? value);
 
        [MethodImpl(MethodImplOptions.InternalCall)]
        internal static extern object? InternalCompareExchange(IntPtr handle, object? value, object? oldValue);
    }
}