Add gsharedvt support functions to the generic sharing code.
authorZoltan Varga <vargaz@gmail.com>
Sat, 19 Jan 2013 02:02:45 +0000 (03:02 +0100)
committerZoltan Varga <vargaz@gmail.com>
Sun, 20 Jan 2013 12:02:12 +0000 (13:02 +0100)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini-generic-sharing.c
mono/mini/mini.c
mono/mini/mini.h

index 3b465ee2785690e5db5ac4cdad2419faa6f2c11d..368b645a01b19c377bb1f4efa8496775eb390797 100644 (file)
@@ -3486,7 +3486,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
 
        iter = NULL;
        while ((method = mono_class_get_methods (klass, &iter))) {
-               if (mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE))
+               if (mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE, FALSE))
                        /* Already added */
                        continue;
 
@@ -3754,7 +3754,7 @@ add_generic_instances (MonoAotCompile *acfg)
                 * If the method is fully sharable, it was already added in place of its
                 * generic definition.
                 */
-               if (mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE))
+               if (mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE, FALSE))
                        continue;
 
                /*
index 196819437ad7282fed49c5d68e139ecf8381444f..417408bacee0d4de1573ec76dfe2f869b6444143 100644 (file)
@@ -3347,7 +3347,7 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method)
        g_assert (klass->inited);
 
        /* Find method index */
-       if (method->is_inflated && mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE)) {
+       if (method->is_inflated && mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE, FALSE)) {
                /* 
                 * For generic methods, we store the fully shared instance in place of the
                 * original method.
@@ -3447,7 +3447,7 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method)
                                return code;
                }
 
-               if (method_index == 0xffffff && method->is_inflated && mono_method_is_generic_sharable_impl_full (method, FALSE, TRUE)) {
+               if (method_index == 0xffffff && method->is_inflated && mono_method_is_generic_sharable_impl_full (method, FALSE, TRUE, FALSE)) {
                        /* Partial sharing */
                        method_index = find_extra_method (mini_get_shared_method (method), &amodule);
                }
index b250f10cbc61bcfa1b4ec92d4fe6b35e6bf795c6..b011211b09d895e11b4286e1795c193cde8e8c7e 100644 (file)
@@ -27,6 +27,9 @@
 static void
 mono_class_unregister_image_generic_subclasses (MonoImage *image, gpointer user_data);
 
+static MonoType*
+mini_get_gsharedvt_alloc_type_gsctx (MonoGenericSharingContext *gsctx, MonoType *t);
+
 static int
 type_check_context_used (MonoType *type, gboolean recursive)
 {
@@ -672,6 +675,11 @@ get_shared_class (MonoClass *class)
         */
        //g_assert_not_reached ();
 
+       /* The gsharedvt changes break this */
+       if (ALLOW_PARTIAL_SHARING)
+               g_assert_not_reached ();
+
+#if 0
        if (class->is_inflated) {
                MonoGenericContext *context = &class->generic_class->context;
                MonoGenericContext *container_context;
@@ -701,6 +709,7 @@ get_shared_class (MonoClass *class)
                        return class;
                }
        }
+#endif
 
        return class_uninstantiated (class);
 }
@@ -1527,6 +1536,7 @@ has_constraints (MonoGenericContainer *container)
  * @method: a method
  * @allow_type_vars: whether to regard type variables as reference types
  * @alloc_partial: whether to allow partial sharing
+ * @alloc_gsharedvt: whenever to allow sharing over valuetypes
  *
  * Returns TRUE iff the method is inflated or part of an inflated
  * class, its context is sharable and it has no constraints on its
@@ -1534,11 +1544,14 @@ has_constraints (MonoGenericContainer *container)
  */
 gboolean
 mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars,
-                                                                                  gboolean allow_partial)
+                                                                                  gboolean allow_partial, gboolean allow_gsharedvt)
 {
        if (!mono_method_is_generic_impl (method))
                return FALSE;
 
+       if (allow_gsharedvt && mini_is_gsharedvt_sharable_method (method))
+               return TRUE;
+
        if (method->is_inflated) {
                MonoMethodInflated *inflated = (MonoMethodInflated*)method;
                MonoGenericContext *context = &inflated->context;
@@ -1574,7 +1587,7 @@ mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_ty
 gboolean
 mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars)
 {
-       return mono_method_is_generic_sharable_impl_full (method, allow_type_vars, ALLOW_PARTIAL_SHARING);
+       return mono_method_is_generic_sharable_impl_full (method, allow_type_vars, ALLOW_PARTIAL_SHARING, TRUE);
 }
 
 gboolean
@@ -1643,6 +1656,7 @@ mono_method_construct_object_context (MonoMethod *method)
 }
 
 static gboolean gshared_supported;
+static gboolean gsharedvt_supported;
 
 void
 mono_set_generic_sharing_supported (gboolean supported)
@@ -1650,6 +1664,12 @@ mono_set_generic_sharing_supported (gboolean supported)
        gshared_supported = supported;
 }
 
+void
+mono_set_generic_sharing_vt_supported (gboolean supported)
+{
+       gsharedvt_supported = supported;
+}
+
 /*
  * mono_class_generic_sharing_enabled:
  * @class: a class
@@ -1842,10 +1862,15 @@ mini_class_get_context (MonoClass *class)
 MonoType*
 mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type)
 {
+       /* FIXME: Some callers don't pass in a gsctx, like mono_dyn_call_prepare () */
+       /*
        if (!type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR))
                g_assert (gsctx);
-
-       return mono_type_get_basic_type_from_generic (type);
+       */
+       if (!type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && mini_is_gsharedvt_type_gsctx (gsctx, type))
+               return mini_get_gsharedvt_alloc_type_gsctx (gsctx, type);
+       else
+               return mono_type_get_basic_type_from_generic (type);
 }
 
 /*
@@ -1859,7 +1884,7 @@ mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type)
 {
        if (type->byref)
                return &mono_defaults.int_class->byval_arg;
-       return mono_type_get_basic_type_from_generic (mono_type_get_underlying_type (type));
+       return mini_get_basic_type_from_generic (gsctx, mono_type_get_underlying_type (type));
 }
 
 /*
@@ -1884,13 +1909,21 @@ mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align)
 /*
  * mini_type_stack_size_full:
  *
- *   Same as mini_type_stack_size, but handle pinvoke data types as well.
+ *   Same as mini_type_stack_size, but handle gsharedvt and pinvoke data types as well.
  */
 int
 mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke)
 {
        int size;
 
+       /*
+       if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR)
+               g_assert (gsctx);
+       */
+
+       if (mini_is_gsharedvt_type_gsctx (gsctx, t))
+               t = mini_get_gsharedvt_alloc_type_gsctx (gsctx, t);
+
        if (pinvoke) {
                size = mono_type_native_stack_size (t, align);
        } else {
@@ -1927,6 +1960,30 @@ mono_generic_sharing_cleanup (void)
                g_hash_table_destroy (generic_subclass_hash);
 }
 
+/*
+ * mini_type_var_is_vt:
+ *
+ *   Return whenever T is a type variable instantiated with a vtype.
+ */
+gboolean
+mini_type_var_is_vt (MonoCompile *cfg, MonoType *type)
+{
+       if (type->type == MONO_TYPE_VAR) {
+               if (cfg->generic_sharing_context->var_is_vt && cfg->generic_sharing_context->var_is_vt [type->data.generic_param->num])
+                       return TRUE;
+               else
+                       return FALSE;
+       } else if (type->type == MONO_TYPE_MVAR) {
+               if (cfg->generic_sharing_context->mvar_is_vt && cfg->generic_sharing_context->mvar_is_vt [type->data.generic_param->num])
+                       return TRUE;
+               else
+                       return FALSE;
+       } else {
+               g_assert_not_reached ();
+       }
+       return FALSE;
+}
+
 gboolean
 mini_type_is_reference (MonoCompile *cfg, MonoType *type)
 {
@@ -1935,5 +1992,81 @@ mini_type_is_reference (MonoCompile *cfg, MonoType *type)
        if (!cfg->generic_sharing_context)
                return FALSE;
        /*FIXME the probably needs better handle under partial sharing*/
-       return type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR;
+       return ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && !mini_type_var_is_vt (cfg, type));
+}
+
+/*
+ * mini_method_get_rgctx:
+ *
+ *  Return the RGCTX which needs to be passed to M when it is called.
+ */
+gpointer
+mini_method_get_rgctx (MonoMethod *m)
+{
+       if (mini_method_get_context (m)->method_inst)
+               return mono_method_lookup_rgctx (mono_class_vtable (mono_domain_get (), m->klass), mini_method_get_context (m)->method_inst);
+       else
+               return mono_class_vtable (mono_domain_get (), m->klass);
+}
+
+#ifdef MONOTOUCH
+
+#include "mini-generic-sharing-gshared.c"
+
+#else
+
+gboolean
+mini_is_gsharedvt_type_gsctx (MonoGenericSharingContext *gsctx, MonoType *t)
+{
+       return FALSE;
+}
+
+gboolean
+mini_is_gsharedvt_type (MonoCompile *cfg, MonoType *t)
+{
+       return FALSE;
 }
+
+gboolean
+mini_is_gsharedvt_klass (MonoCompile *cfg, MonoClass *klass)
+{
+       return FALSE;
+}
+
+gboolean
+mini_is_gsharedvt_signature (MonoCompile *cfg, MonoMethodSignature *sig)
+{
+       return FALSE;
+}
+
+gboolean
+mini_is_gsharedvt_variable_type (MonoCompile *cfg, MonoType *t)
+{
+       return FALSE;
+}
+
+static MonoType*
+mini_get_gsharedvt_alloc_type_gsctx (MonoGenericSharingContext *gsctx, MonoType *t)
+{
+       return NULL;
+}
+
+MonoType*
+mini_get_gsharedvt_alloc_type_for_type (MonoCompile *cfg, MonoType *t)
+{
+       return NULL;
+}
+
+gboolean
+mini_is_gsharedvt_sharable_method (MonoMethod *method)
+{
+       return FALSE;
+}
+
+gboolean
+mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig)
+{
+       return FALSE;
+}
+
+#endif /* !MONOTOUCH */
index a80150fa634f52978c3dacb5f6f61fb61d00a97f..6fb87d3708d7c34ce29c4987d389f41eb1fb3d6d 100644 (file)
@@ -4230,7 +4230,7 @@ mini_get_shared_method (MonoMethod *method)
                shared_context = declaring_method->klass->generic_container->context;
 
        /* Handle partial sharing */
-       if (method != declaring_method && method->is_inflated && !mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE)) {
+       if (method != declaring_method && method->is_inflated && !mono_method_is_generic_sharable_impl_full (method, FALSE, FALSE, FALSE)) {
                MonoGenericContext *context = mono_method_get_context (method);
                MonoGenericInst *inst;
                MonoType **type_argv;
index 0a3ee8b5515be51b74b408df123287dcad9a159c..50dafa8542683b1e5005ec019d410066b3548d55 100644 (file)
@@ -2335,10 +2335,12 @@ MonoArray* ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip
 
 /* Generic sharing */
 
-
 void
 mono_set_generic_sharing_supported (gboolean supported) MONO_INTERNAL;
 
+void
+mono_set_generic_sharing_vt_supported (gboolean supported) MONO_INTERNAL;
+
 gboolean
 mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
 
@@ -2386,7 +2388,7 @@ gboolean
 mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
 
 gboolean
-mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial) MONO_INTERNAL;
+mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial, gboolean allow_gsharedvt) MONO_INTERNAL;
 
 gboolean
 mono_is_partially_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
@@ -2423,7 +2425,17 @@ void mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint
 
 void mono_cfg_set_exception (MonoCompile *cfg, int type) MONO_INTERNAL;
 gboolean mini_type_is_reference (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
-
+gboolean mini_type_var_is_vt (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_klass (MonoCompile *cfg, MonoClass *klass) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_signature (MonoCompile *cfg, MonoMethodSignature *sig) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_type_gsctx (MonoGenericSharingContext *gsctx, MonoType *t) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_variable_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
+MonoType* mini_get_gsharedvt_alloc_type_for_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_sharable_method (MonoMethod *method) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig) MONO_INTERNAL;
+gpointer mini_method_get_rgctx (MonoMethod *m) MONO_INTERNAL;
+void mini_init_gsctx (MonoGenericContext *context, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
 
 /* wapihandles.c */
 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;