[mono][interp] Remove null check during initblk/cpblk with size 0 (#63086)
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 23 Dec 2021 08:46:50 +0000 (10:46 +0200)
committerGitHub <noreply@github.com>
Thu, 23 Dec 2021 08:46:50 +0000 (09:46 +0100)
src/libraries/System.Private.CoreLib/src/System/Span.cs
src/mono/mono/mini/interp/interp.c

index a5580b2..b512a53 100644 (file)
@@ -284,18 +284,11 @@ namespace System
         {
             if (Unsafe.SizeOf<T>() == 1)
             {
-#if MONO
-                // Mono runtime's implementation of initblk performs a null check on the address.
-                // We'll perform a length check here to avoid passing a null address in the empty span case.
-                if (_length != 0)
-#endif
-                {
-                    // Special-case single-byte types like byte / sbyte / bool.
-                    // The runtime eventually calls memset, which can efficiently support large buffers.
-                    // We don't need to check IsReferenceOrContainsReferences because no references
-                    // can ever be stored in types this small.
-                    Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref _pointer.Value), Unsafe.As<T, byte>(ref value), (uint)_length);
-                }
+                // Special-case single-byte types like byte / sbyte / bool.
+                // The runtime eventually calls memset, which can efficiently support large buffers.
+                // We don't need to check IsReferenceOrContainsReferences because no references
+                // can ever be stored in types this small.
+                Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref _pointer.Value), Unsafe.As<T, byte>(ref value), (uint)_length);
             }
             else
             {
index 56d4134..040e116 100644 (file)
@@ -6804,18 +6804,20 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
                MINT_IN_CASE(MINT_CPBLK) {
                        gpointer dest = LOCAL_VAR (ip [1], gpointer);
                        gpointer src = LOCAL_VAR (ip [2], gpointer);
-                       if (!dest || !src)
+                       guint32 size = LOCAL_VAR (ip [3], guint32);
+                       if (size && (!dest || !src))
                                THROW_EX (mono_get_exception_null_reference(), ip);
-                       /* FIXME: value and size may be int64... */
-                       memcpy (dest, src, LOCAL_VAR (ip [3], gint32));
+                       else
+                               memcpy (dest, src, size);
                        ip += 4;
                        MINT_IN_BREAK;
                }
                MINT_IN_CASE(MINT_INITBLK) {
                        gpointer dest = LOCAL_VAR (ip [1], gpointer);
-                       NULL_CHECK (dest);
-                       /* FIXME: value and size may be int64... */
-                       memset (dest, LOCAL_VAR (ip [2], gint32), LOCAL_VAR (ip [3], gint32));
+                       guint32 size = LOCAL_VAR (ip [3], guint32);
+                       if (size)
+                               NULL_CHECK (dest);
+                       memset (dest, LOCAL_VAR (ip [2], gint32), size);
                        ip += 4;
                        MINT_IN_BREAK;
                }