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.
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;
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);
int
mono_type_size (MonoType *t, int *align)
{
+ MonoTypeEnum simple_type;
+
if (!t) {
*align = 1;
return 0;
return sizeof (gpointer);
}
- switch (t->type){
+ simple_type = t->type;
+ again:
+ switch (simple_type) {
case MONO_TYPE_VOID:
*align = 1;
return 0;
}
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);
}
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);
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:
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;
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)
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;
/*
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);
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);
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;
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));
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;
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
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;
}
}
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;
}
}
}
#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 */