[jit] Allow reference types with Array.UnsafeMov. Document restrictrions in Array.cs.
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 11 Nov 2015 23:30:00 +0000 (18:30 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 11 Nov 2015 23:30:00 +0000 (18:30 -0500)
mcs/class/corlib/System/Array.cs
mono/mini/method-to-ir.c

index 32e873227de30ee98a4cafc752a52642ff3bdf31..8f6e0aa098e40b238d2738503705207086c3eb80 100644 (file)
@@ -3189,6 +3189,19 @@ namespace System
                //
                // Moved value from instance into target of different type with no checks (JIT intristics)
                //
+               // Restrictions:
+               //
+               // S and R must either:
+               //       both be blitable valuetypes
+               //       both be reference types (IOW, an unsafe cast)
+               // S and R cannot be float or double
+               // S and R must either:
+               //       both be a struct
+               //       both be a scalar
+               // S and R must either:
+               //       be of same size
+               //       both be a scalar of size <= 4
+               //
                internal static R UnsafeMov<S,R> (S instance) {
                        return (R)(object) instance;
                }
index c4553b90815fd8b4a045872cdd32a32869c5af93..10655663a538d7af0ffb32a1b29c2efedfa25691 100644 (file)
@@ -5694,13 +5694,19 @@ is_unsafe_mov_compatible (MonoCompile *cfg, MonoClass *param_klass, MonoClass *r
        if (cfg->verbose_level > 3)
                printf ("[UNSAFE-MOV-INTRISIC] %s <- %s\n", return_klass->name, param_klass->name);
 
-       //Only allow for valuetypes
-       if (!param_klass->valuetype || !return_klass->valuetype) {
+       //Don't allow mixing reference types with value types
+       if (param_klass->valuetype != return_klass->valuetype) {
                if (cfg->verbose_level > 3)
-                       printf ("[UNSAFE-MOV-INTRISIC]\tone of the args is not a valuetype\n");
+                       printf ("[UNSAFE-MOV-INTRISIC]\tone of the args is a valuetype and the other is not\n");
                return FALSE;
        }
 
+       if (!param_klass->valuetype) {
+               if (cfg->verbose_level > 3)
+                       printf ("[UNSAFE-MOV-INTRISIC]\targs are reference types\n");
+               return TRUE;
+       }
+
        //That are blitable
        if (param_klass->has_references || return_klass->has_references)
                return FALSE;