[jit] Compute the instance size/alignment correctly for gshared types whose constrain...
authormonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 23 Jan 2020 14:43:49 +0000 (09:43 -0500)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 23 Jan 2020 14:43:49 +0000 (15:43 +0100)
Fixes mono/mono#18455

src/mono/mono/metadata/class-init.c
src/mono/mono/mini/gshared.cs

index 71eaf37..a402b43 100644 (file)
@@ -1187,7 +1187,7 @@ static MonoClass*
 make_generic_param_class (MonoGenericParam *param)
 {
        MonoClass *klass, **ptr;
-       int count, pos, i;
+       int count, pos, i, min_align;
        MonoGenericParamInfo *pinfo = mono_generic_param_info (param);
        MonoGenericContainer *container = mono_generic_param_owner (param);
        g_assert_checked (container);
@@ -1260,13 +1260,12 @@ make_generic_param_class (MonoGenericParam *param)
        /* We don't use type_token for VAR since only classes can use it (not arrays, pointer, VARs, etc) */
        klass->sizes.generic_param_token = !is_anonymous ? pinfo->token : 0;
 
-       /*Init these fields to sane values*/
-       klass->min_align = 1;
        /*
         * This makes sure the the value size of this class is equal to the size of the types the gparam is
         * constrained to, the JIT depends on this.
         */
-       klass->instance_size = MONO_ABI_SIZEOF (MonoObject) + mono_type_stack_size_internal (m_class_get_byval_arg (klass), NULL, TRUE);
+       klass->instance_size = MONO_ABI_SIZEOF (MonoObject) + mono_type_size (m_class_get_byval_arg (klass), &min_align);
+       klass->min_align = min_align;
        mono_memory_barrier ();
        klass->size_inited = 1;
 
@@ -3905,7 +3904,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_
 
        MonoType *klass_byval_arg = m_class_get_byval_arg (klass);
        if (klass_byval_arg->type == MONO_TYPE_VAR || klass_byval_arg->type == MONO_TYPE_MVAR)
-               instance_size = MONO_ABI_SIZEOF (MonoObject) + mono_type_stack_size_internal (klass_byval_arg, NULL, TRUE);
+               instance_size = MONO_ABI_SIZEOF (MonoObject) + mono_type_size (klass_byval_arg, &min_align);
        else if (klass_byval_arg->type == MONO_TYPE_PTR)
                instance_size = MONO_ABI_SIZEOF (MonoObject) + MONO_ABI_SIZEOF (gpointer);
 
index 7dffba3..c2903f0 100644 (file)
@@ -2249,6 +2249,27 @@ public class Tests
                return (c.Foo () == "abcd") ? 0 : 1;
        }
 #endif
+
+       class KvpList<T> {
+               public T[] array = new T[4];
+               int size = 0;
+
+               [MethodImpl(MethodImplOptions.NoInlining)]
+               public void MyAdd(T item) {
+                       if (size < (uint)array.Length) {
+                               array [size] = item;
+                               size++;
+                       }
+               }
+       }
+
+       public static int test_0_regress_18455 () {
+               var p = new KvpList<KeyValuePair<int, KeyValuePair<int,int>>> ();
+               KeyValuePair<int, KeyValuePair<int,int>> kvp = new KeyValuePair<int, KeyValuePair<int,int>> (3, new KeyValuePair<int,int> (1, 2));
+
+               p.MyAdd (kvp);
+               return p.array [1].Key == 0 ? 0 : 1;
+       }
 }
 
 // #13191