[jit] Rename MonoGenericParam->serial to 'gshared_constraint', use it to calculate...
authorZoltan Varga <vargaz@gmail.com>
Sun, 8 Mar 2015 03:59:25 +0000 (22:59 -0500)
committerZoltan Varga <vargaz@gmail.com>
Sun, 8 Mar 2015 03:59:34 +0000 (22:59 -0500)
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/metadata.c
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini-runtime.c
mono/mini/mini.c

index fcd8a85963d9789a88ee60784565e029d84d7921..bd6c239328fa62f6a0c65360c9c8b71b477462ef 100644 (file)
@@ -563,12 +563,14 @@ struct _MonoDynamicGenericClass {
 struct _MonoGenericParam {
        /*
         * Type or method this parameter was defined in.
-        * If this is non-null, this is a MonoGenericParamFull structure.
         */
        MonoGenericContainer *owner;
        guint16 num;
-       /* For internal runtime use, used to make different versions of the same param */
-       guint16 serial;
+       /*
+        * If != 0, this is a generated generic param used by the JIT to implement generic
+        * sharing.
+        */
+       MonoTypeEnum gshared_constraint;
        /* 
         * If owner is NULL, or owner is 'owned' by this gparam,
         * then this is the image whose mempool this struct was allocated from.
index b70897dccb00767160a66906636e4a11d355eba9..22448a65ff74ac0acbc2a9e148a8cf329c9c1bca 100644 (file)
@@ -6178,7 +6178,7 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
 static MonoClass *
 get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_lock)
 {
-       int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
+       int n = mono_generic_param_num (param) | ((guint32)param->gshared_constraint << 16);
        MonoImage *image = param->image;
        GHashTable *ht;
 
@@ -6209,7 +6209,7 @@ get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_
 static void
 set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
 {
-       int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
+       int n = mono_generic_param_num (param) | ((guint32)param->gshared_constraint << 16);
        MonoImage *image = param->image;
 
        g_assert (image);
index 26d079d20e944d5c5e2849d4d5093c94170a381a..432c26f073e9fb89f06a5322326a24558c546d23 100644 (file)
@@ -4345,6 +4345,8 @@ mono_type_set_alignment (MonoTypeEnum type, int align)
 int
 mono_type_size (MonoType *t, int *align)
 {
+       MonoTypeEnum simple_type;
+
        if (!t) {
                *align = 1;
                return 0;
@@ -4354,7 +4356,9 @@ mono_type_size (MonoType *t, int *align)
                return sizeof (gpointer);
        }
 
-       switch (t->type){
+       simple_type = t->type;
+ again:
+       switch (simple_type) {
        case MONO_TYPE_VOID:
                *align = 1;
                return 0;
@@ -4427,9 +4431,14 @@ mono_type_size (MonoType *t, int *align)
        }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
-               /* FIXME: Martin, this is wrong. */
-               *align = MONO_ABI_ALIGNOF (gpointer);
-               return sizeof (gpointer);
+               if (t->data.generic_param->gshared_constraint == 0 || t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE) {
+                       *align = MONO_ABI_ALIGNOF (gpointer);
+                       return sizeof (gpointer);
+               } else {
+                       /* The gparam can only match types given by gshared_constraint */
+                       simple_type = t->data.generic_param->gshared_constraint;
+                       goto again;
+               }
        default:
                g_error ("mono_type_size: type 0x%02x unknown", t->type);
        }
@@ -4453,6 +4462,7 @@ int
 mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
 {
        int tmp;
+       MonoTypeEnum simple_type;
 #if SIZEOF_VOID_P == SIZEOF_REGISTER
        int stack_slot_size = sizeof (gpointer);
        int stack_slot_align = MONO_ABI_ALIGNOF (gpointer);
@@ -4471,7 +4481,9 @@ mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
                return stack_slot_size;
        }
 
-       switch (t->type){
+       simple_type = t->type;
+ again:
+       switch (simple_type) {
        case MONO_TYPE_BOOLEAN:
        case MONO_TYPE_CHAR:
        case MONO_TYPE_I1:
@@ -4494,8 +4506,14 @@ mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                g_assert (allow_open);
-               *align = stack_slot_align;
-               return stack_slot_size;
+               if (t->data.generic_param->gshared_constraint == 0 || t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE) {
+                       *align = stack_slot_align;
+                       return stack_slot_size;
+               } else {
+                       /* The gparam can only match types given by gshared_constraint */
+                       simple_type = t->data.generic_param->gshared_constraint;
+                       goto again;
+               }
        case MONO_TYPE_TYPEDBYREF:
                *align = stack_slot_align;
                return stack_slot_size * 3;
@@ -4688,7 +4706,7 @@ mono_metadata_generic_param_hash (MonoGenericParam *p)
        guint hash;
        MonoGenericParamInfo *info;
 
-       hash = (mono_generic_param_num (p) << 2) | p->serial;
+       hash = (mono_generic_param_num (p) << 2) | p->gshared_constraint;
        info = mono_generic_param_info (p);
        /* Can't hash on the owner klass/method, since those might not be set when this is called */
        if (info)
@@ -4703,7 +4721,7 @@ mono_metadata_generic_param_equal (MonoGenericParam *p1, MonoGenericParam *p2, g
                return TRUE;
        if (mono_generic_param_num (p1) != mono_generic_param_num (p2))
                return FALSE;
-       if (p1->serial != p2->serial)
+       if (p1->gshared_constraint != p2->gshared_constraint)
                return FALSE;
 
        /*
index 21f49be0a5ecc18b79171bbcf1598620b3108d5c..2f47ccf27f57f3163c20b50771b0c1f4e829c0e1 100644 (file)
@@ -2495,13 +2495,13 @@ encode_klass_ref_inner (MonoAotCompile *acfg, MonoClass *klass, guint8 *buf, gui
                encode_value (container ? 1 : 0, p, &p);
                if (container) {
                        encode_value (container->is_method, p, &p);
-                       g_assert (par->serial == 0);
+                       g_assert (par->gshared_constraint == 0);
                        if (container->is_method)
                                encode_method_ref (acfg, container->owner.method, p, &p);
                        else
                                encode_klass_ref (acfg, container->owner.klass, p, &p);
                } else {
-                       encode_value (par->serial, p, &p);
+                       encode_value (par->gshared_constraint, p, &p);
                }
        } else if (klass->byval_arg.type == MONO_TYPE_PTR) {
                encode_value (MONO_AOT_TYPEREF_PTR, p, &p);
index 7a90bfe458adfb4ad85479e7dd4d85a3dcf2c6a0..c23fe17c49b879114bec439a38a6bb6d1275660a 100644 (file)
@@ -467,7 +467,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                int type = decode_value (p, &p);
                int num = decode_value (p, &p);
                gboolean has_container = decode_value (p, &p);
-               int serial = 0;
+               MonoTypeEnum gshared_constraint = 0;
 
                if (has_container) {
                        gboolean is_method = decode_value (p, &p);
@@ -490,19 +490,19 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                                container = class_def->generic_container;
                        }
                } else {
-                       serial = decode_value (p, &p);
+                       gshared_constraint = decode_value (p, &p);
                }
 
                t = g_new0 (MonoType, 1);
                t->type = type;
                if (container) {
                        t->data.generic_param = mono_generic_container_get_param (container, num);
-                       g_assert (serial == 0);
+                       g_assert (gshared_constraint == 0);
                } else {
                        /* Anonymous */
                        MonoGenericParam *par = (MonoGenericParam*)mono_image_alloc0 (module->assembly->image, sizeof (MonoGenericParamFull));
                        par->num = num;
-                       par->serial = serial;
+                       par->gshared_constraint = gshared_constraint;
                        // FIXME:
                        par->image = mono_defaults.corlib;
                        t->data.generic_param = par;
index bafc1f37dfffb7068bf61ca027b6e77ddb6d577a..7e383ea1ae1493bfc3582de7611f38708c8e5e41 100755 (executable)
@@ -1670,7 +1670,7 @@ get_gsharedvt_type (MonoType *t)
        MonoImage *image = NULL;
 
        /*
-        * Create an anonymous gparam with a different serial so normal gshared and gsharedvt methods have
+        * Create an anonymous gparam with a different gshared_constraint so normal gshared and gsharedvt methods have
         * a different instantiation.
         */
        g_assert (mono_generic_param_info (par));
@@ -1692,7 +1692,7 @@ get_gsharedvt_type (MonoType *t)
        copy->owner = NULL;
        // FIXME:
        copy->image = mono_defaults.corlib;
-       copy->serial = 1;
+       copy->gshared_constraint = MONO_TYPE_VALUETYPE;
        res = mono_metadata_type_dup (NULL, t);
        res->data.generic_param = copy;
 
@@ -1709,33 +1709,7 @@ get_gsharedvt_type (MonoType *t)
 static gboolean
 is_gsharedvt_type (MonoType *t)
 {
-       return (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->serial == 1;
-}
-
-/* Return whenever METHOD is a gsharedvt method */
-static gboolean
-is_gsharedvt_method (MonoMethod *method)
-{
-       MonoGenericContext *context;
-       MonoGenericInst *inst;
-       int i;
-
-       if (!method->is_inflated)
-               return FALSE;
-       context = mono_method_get_context (method);
-       inst = context->class_inst;
-       if (inst) {
-               for (i = 0; i < inst->type_argc; ++i)
-                       if (is_gsharedvt_type (inst->type_argv [i]))
-                               return TRUE;
-       }
-       inst = context->method_inst;
-       if (inst) {
-               for (i = 0; i < inst->type_argc; ++i)
-                       if (is_gsharedvt_type (inst->type_argv [i]))
-                               return TRUE;
-       }
-       return FALSE;
+       return (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE;
 }
 
 static gboolean
@@ -1877,7 +1851,7 @@ mini_init_gsctx (MonoDomain *domain, MonoMemPool *mp, MonoGenericContext *contex
                for (i = 0; i < inst->type_argc; ++i) {
                        MonoType *type = inst->type_argv [i];
 
-                       if ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && type->data.generic_param->serial == 1)
+                       if (is_gsharedvt_type (type))
                                gsctx->var_is_vt [i] = TRUE;
                }
        }
@@ -1893,7 +1867,7 @@ mini_init_gsctx (MonoDomain *domain, MonoMemPool *mp, MonoGenericContext *contex
                for (i = 0; i < inst->type_argc; ++i) {
                        MonoType *type = inst->type_argv [i];
 
-                       if ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && type->data.generic_param->serial == 1)
+                       if (is_gsharedvt_type (type))
                                gsctx->mvar_is_vt [i] = TRUE;
                }
        }
index d13da0d96ae55d49df6ea225e6b8fd4492378086..3f0eb344859f5dc83074162572245c0b1a581b24 100755 (executable)
@@ -3018,55 +3018,10 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
 }
 #endif
 
-static MonoType*
-get_gsharedvt_type (MonoType *t)
-{
-       MonoGenericParam *par = t->data.generic_param;
-       MonoGenericParam *copy;
-       MonoType *res;
-       MonoImage *image = NULL;
-
-       /* 
-        * Create an anonymous gparam with a different serial so normal gshared and gsharedvt methods have
-        * a different instantiation.
-        */
-       g_assert (mono_generic_param_info (par));
-       if (par->owner) {
-               image = par->owner->image;
-
-               mono_image_lock (image);
-               if (!image->gsharedvt_types)
-                       image->gsharedvt_types = g_hash_table_new (NULL, NULL);
-               res = g_hash_table_lookup (image->gsharedvt_types, par);
-               mono_image_unlock (image);
-               if (res)
-                       return res;
-               copy = mono_image_alloc0 (image, sizeof (MonoGenericParamFull));
-               memcpy (copy, par, sizeof (MonoGenericParamFull));
-       } else {
-               copy = g_memdup (par, sizeof (MonoGenericParam));
-       }
-       copy->owner = NULL;
-       // FIXME:
-       copy->image = mono_defaults.corlib;
-       copy->serial = 1;
-       res = mono_metadata_type_dup (NULL, t);
-       res->data.generic_param = copy;
-
-       if (par->owner) {
-               mono_image_lock (image);
-               /* Duplicates are ok */
-               g_hash_table_insert (image->gsharedvt_types, par, res);
-               mono_image_unlock (image);
-       }
-
-       return res;
-}
-
 static gboolean
 is_gsharedvt_type (MonoType *t)
 {
-       return (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->serial == 1;
+       return (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE;
 }
 
 /* Return whenever METHOD is a gsharedvt method */