Repository: dotnet/runtime
File: src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs (C#)

Code before:
        /// <exception cref="ArgumentException"><paramref name="type" /> must be a type provided by the runtime.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="size" /> is negative.</exception>
        public static unsafe IntPtr AllocateTypeAssociatedMemory(Type type, int size)
        {
            if (type is not RuntimeType)
            {
                throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
            }

            ArgumentOutOfRangeException.ThrowIfNegative(size);

            // We don't support unloading; the memory will never be freed.
            return (IntPtr)NativeMemory.AllocZeroed((uint)size);
        }

        /// <summary>Allocates aligned memory that's associated with the <paramref name="type" /> and is freed if and when the <see cref="Type" /> is unloaded.</summary>
        /// <param name="type">The type associated with the allocated memory.</param>
        /// <param name="size">The amount of memory to allocate, in bytes.</param>
        /// <param name="alignment">The alignment, in bytes, of the memory to allocate. This must be a power of <c>2</c>.</param>
        /// <returns>The allocated aligned memory.</returns>
        /// <exception cref="ArgumentException"><paramref name="type" /> must be a type provided by the runtime.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="size" /> is negative.</exception>
        /// <exception cref="ArgumentException"><paramref name="alignment" /> is not a power of <c>2</c>.</exception>
        public static IntPtr AllocateTypeAssociatedMemory(Type type, int size, int alignment)
        {
            if (type is not RuntimeType rt)
            {
                throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
            }

            ArgumentOutOfRangeException.ThrowIfNegative(size);

            if (!BitOperations.IsPow2(alignment))
            {
                // The C standard doesn't define what a valid alignment is, however Windows and POSIX implementation requires a power of 2
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AlignmentMustBePow2);
            }

            // We don't support unloading; the memory will never be freed.
            void* result = NativeMemory.AlignedAlloc((uint)size, (uint)alignment);
            NativeMemory.Clear(result, (uint)size);
            return (IntPtr)result;
        }

        [Intrinsic]
        internal static ref byte GetRawData(this object obj) => ref obj.GetRawData();

        [Intrinsic]
        internal static bool IsBitwiseEquatable<T>() => IsBitwiseEquatable<T>();

        [Intrinsic]

Review comment (refactor):
The variable `rt` is declared but never used. Since Mono doesn't pass the type to a native function, you can simplify this to `if (type is not RuntimeType)` to match the pattern used in the non-aligned overload (line 150).
```suggestion
            if (type is not RuntimeType)
```

Code after:
        /// <returns>The allocated memory.</returns>
        /// <exception cref="ArgumentException"><paramref name="type" /> must be a type provided by the runtime.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="size" /> is negative.</exception>
        public static unsafe IntPtr AllocateTypeAssociatedMemory(Type type, int size)
        {
            if (type is not RuntimeType)
            {
                throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
            }

            ArgumentOutOfRangeException.ThrowIfNegative(size);

            // We don't support unloading; the memory will never be freed.
            return (IntPtr)NativeMemory.AllocZeroed((uint)size);
        }

        /// <summary>Allocates aligned memory that's associated with the <paramref name="type" /> and is freed if and when the <see cref="Type" /> is unloaded.</summary>
        /// <param name="type">The type associated with the allocated memory.</param>
        /// <param name="size">The amount of memory to allocate, in bytes.</param>
        /// <param name="alignment">The alignment, in bytes, of the memory to allocate. This must be a power of <c>2</c>.</param>
        /// <returns>The allocated aligned memory.</returns>
        /// <exception cref="ArgumentException"><paramref name="type" /> must be a type provided by the runtime.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="size" /> is negative.</exception>
        /// <exception cref="ArgumentException"><paramref name="alignment" /> is not a power of <c>2</c>.</exception>
        public static unsafe IntPtr AllocateTypeAssociatedMemory(Type type, int size, int alignment)
        {
            if (type is not RuntimeType)
            {
                throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
            }

            ArgumentOutOfRangeException.ThrowIfNegative(size);

            if (!BitOperations.IsPow2(alignment))
            {
                // The C standard doesn't define what a valid alignment is, however Windows and POSIX implementation requires a power of 2
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AlignmentMustBePow2);
            }

            // We don't support unloading; the memory will never be freed.
            void* result = NativeMemory.AlignedAlloc((uint)size, (uint)alignment);
            NativeMemory.Clear(result, (uint)size);
            return (IntPtr)result;
        }

        [Intrinsic]
        internal static ref byte GetRawData(this object obj) => ref obj.GetRawData();

        [Intrinsic]
        internal static bool IsBitwiseEquatable<T>() => IsBitwiseEquatable<T>();