2008-06-13 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Fri, 13 Jun 2008 11:46:50 +0000 (11:46 -0000)
committerMark Probst <mark.probst@gmail.com>
Fri, 13 Jun 2008 11:46:50 +0000 (11:46 -0000)
* generic-sharing.c: Code for maintaining the MRGCTX and MRGCTX
templates.  Templates are generalized with an additional type_argc
argument.  RGCTX templates have type_argc==0, MRGCTX templates
have type_argc>0.

* domain-internals.h, domain.c: New hash table for looking up
MRGCTXs.

* metadata.c, metadata-internals.h: Rename hash and equal
functions for MonoGenericInst's and make them public.

* class-internals.h: New data structures for the MRGCTX.  Macros
for distinguishing slots in the RGCTX and the MRGCTX.

2008-06-13  Mark Probst  <mark.probst@gmail.com>

* mini.c, generic-sharing.c: Removed generic class relations.

* mini.c, tramp-amd64.c, tramp-x86.c: Additional arguments to
functions due to MRGCTX changes.

svn path=/trunk/mono/; revision=105766

12 files changed:
mono/metadata/ChangeLog
mono/metadata/class-internals.h
mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/metadata/generic-sharing.c
mono/metadata/metadata-internals.h
mono/metadata/metadata.c
mono/mini/ChangeLog
mono/mini/generic-sharing.c
mono/mini/mini.c
mono/mini/tramp-amd64.c
mono/mini/tramp-x86.c

index fcc8be8d8759c943ff4f74279b7593ad789f5069..e8c50d46ac7609e4bccff635fd3f41cb50dd5664 100644 (file)
@@ -1,3 +1,19 @@
+2008-06-13  Mark Probst  <mark.probst@gmail.com>
+
+       * generic-sharing.c: Code for maintaining the MRGCTX and MRGCTX
+       templates.  Templates are generalized with an additional type_argc
+       argument.  RGCTX templates have type_argc==0, MRGCTX templates
+       have type_argc>0.
+
+       * domain-internals.h, domain.c: New hash table for looking up
+       MRGCTXs.
+
+       * metadata.c, metadata-internals.h: Rename hash and equal
+       functions for MonoGenericInst's and make them public.
+
+       * class-internals.h: New data structures for the MRGCTX.  Macros
+       for distinguishing slots in the RGCTX and the MRGCTX.
+
 2008-06-13  Mark Probst  <mark.probst@gmail.com>
 
        * object.c (mono_method_get_imt_slot): Put the same methods of
index 649f1a818a771c1603569d055d9c723a2f822c31..5ba44b169f0c939bea99e500653e47938d45a62a 100644 (file)
@@ -215,7 +215,8 @@ enum {
        MONO_RGCTX_INFO_REFLECTION_TYPE,
        MONO_RGCTX_INFO_METHOD,
        MONO_RGCTX_INFO_GENERIC_METHOD_CODE,
-       MONO_RGCTX_INFO_CLASS_FIELD
+       MONO_RGCTX_INFO_CLASS_FIELD,
+       MONO_RGCTX_INFO_METHOD_RGCTX
 };
 
 typedef struct _MonoRuntimeGenericContextOtherInfoTemplate {
@@ -227,8 +228,21 @@ typedef struct _MonoRuntimeGenericContextOtherInfoTemplate {
 typedef struct {
        MonoClass *next_subclass;
        MonoRuntimeGenericContextOtherInfoTemplate *other_infos;
+       GSList *method_templates;
 } MonoRuntimeGenericContextTemplate;
 
+typedef struct {
+       MonoVTable *class_vtable; /* must be the first element */
+       MonoGenericInst *method_inst;
+       gpointer infos [MONO_ZERO_LEN_ARRAY];
+} MonoMethodRuntimeGenericContext;
+
+#define MONO_RGCTX_SLOT_MAKE_RGCTX(i)  (i)
+#define MONO_RGCTX_SLOT_MAKE_MRGCTX(i) ((i) | 0x80000000)
+#define MONO_RGCTX_SLOT_INDEX(s)       ((s) & 0x7fffffff)
+#define MONO_RGCTX_SLOT_IS_MRGCTX(s)   (((s) & 0x80000000) ? TRUE : FALSE)
+
+
 #define MONO_CLASS_PROP_EXCEPTION_DATA 0
 
 struct _MonoClass {
@@ -970,6 +984,9 @@ mono_type_get_full        (MonoImage *image, guint32 type_token, MonoGenericCont
 gboolean
 mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) MONO_INTERNAL;
 
+MonoMethod*
+mono_method_get_declaring_generic_method (MonoMethod *method) MONO_INTERNAL;
+
 MonoType*
 mono_type_get_basic_type_from_generic (MonoType *type) MONO_INTERNAL;
 
@@ -979,11 +996,18 @@ mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
 gpointer
 mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot) MONO_INTERNAL;
 
+gpointer
+mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot) MONO_INTERNAL;
+
+MonoMethodRuntimeGenericContext*
+mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst) MONO_INTERNAL;
+
 int
-mono_class_rgctx_get_array_size (int n) MONO_INTERNAL;
+mono_class_rgctx_get_array_size (int n, gboolean mrgctx) MONO_INTERNAL;
 
-gboolean
-mono_class_lookup_or_register_other_info (MonoClass *class, gpointer data, int info_type, MonoGenericContext *generic_context) MONO_INTERNAL;
+guint32
+mono_method_lookup_or_register_other_info (MonoMethod *method, gboolean in_mrgctx, gpointer data,
+       int info_type, MonoGenericContext *generic_context) MONO_INTERNAL;
 
 int
 mono_generic_context_check_used (MonoGenericContext *context) MONO_INTERNAL;
index dc0861b8b1b9b0141dae43db2178b0ef7cd3132c..bbcce6c075dc92a9ee9d6d0d2cacee1031de260a 100644 (file)
@@ -203,6 +203,7 @@ struct _MonoDomain {
        CRITICAL_SECTION    assemblies_lock;
 
        GHashTable         *shared_generics_hash;
+       GHashTable         *method_rgctx_hash;
 };
 
 typedef struct  {
index 52bfa6dc908f545a3194abde49562e890d4f4c71..ae8ec5b37a91888bea1b67ff956d45335fd5c32b 100644 (file)
@@ -1165,6 +1165,7 @@ mono_domain_create (void)
        InitializeCriticalSection (&domain->assemblies_lock);
 
        domain->shared_generics_hash = NULL;
+       domain->method_rgctx_hash = NULL;
 
        mono_appdomains_lock ();
        domain_id_alloc (domain);
@@ -1925,6 +1926,10 @@ mono_domain_free (MonoDomain *domain, gboolean force)
                g_hash_table_destroy (domain->shared_generics_hash);
                domain->shared_generics_hash = NULL;
        }
+       if (domain->method_rgctx_hash) {
+               g_hash_table_destroy (domain->method_rgctx_hash);
+               domain->method_rgctx_hash = NULL;
+       }
 
        DeleteCriticalSection (&domain->assemblies_lock);
        DeleteCriticalSection (&domain->lock);
index 145d4dfb9b0298dac6683bf00680594db8a9be30..97e596fa98282d74c5f73a9ead9c8e65ab43e1be 100644 (file)
@@ -20,6 +20,7 @@
 #include "class.h"
 #include "class-internals.h"
 #include "marshal.h"
+#include "debug-helpers.h"
 
 static int
 type_check_context_used (MonoType *type, gboolean recursive)
@@ -114,6 +115,9 @@ mono_class_check_context_used (MonoClass *class)
 /*
  * Guards the two global rgctx (template) hash tables and all rgctx
  * templates.
+ *
+ * Ordering: The loader lock can be taken while the templates lock is
+ * held.
  */
 static CRITICAL_SECTION templates_mutex;
 
@@ -144,14 +148,61 @@ templates_unlock (void)
  * LOCKING: templates lock
  */
 static MonoRuntimeGenericContextOtherInfoTemplate*
-rgctx_template_get_other_slot (MonoRuntimeGenericContextTemplate *template, int slot)
+get_other_info_templates (MonoRuntimeGenericContextTemplate *template, int type_argc)
+{
+       g_assert (type_argc >= 0);
+       if (type_argc == 0)
+               return template->other_infos;
+       return g_slist_nth_data (template->method_templates, type_argc - 1);
+}
+
+/*
+ * LOCKING: templates lock
+ */
+static void
+set_other_info_templates (MonoRuntimeGenericContextTemplate *template, int type_argc,
+       MonoRuntimeGenericContextOtherInfoTemplate *oti)
+{
+       g_assert (type_argc >= 0);
+       if (type_argc == 0)
+               template->other_infos = oti;
+       else {
+               int length = g_slist_length (template->method_templates);
+               GSList *list;
+
+               /* FIXME: quadratic! */
+               while (length < type_argc) {
+                       template->method_templates = g_slist_append (template->method_templates, NULL);
+                       length++;
+               }
+
+               list = g_slist_nth (template->method_templates, type_argc - 1);
+               g_assert (list);
+               list->data = oti;
+       }
+}
+
+/*
+ * LOCKING: templates lock
+ */
+static int
+template_get_max_argc (MonoRuntimeGenericContextTemplate *template)
+{
+       return g_slist_length (template->method_templates);
+}
+
+/*
+ * LOCKING: templates lock
+ */
+static MonoRuntimeGenericContextOtherInfoTemplate*
+rgctx_template_get_other_slot (MonoRuntimeGenericContextTemplate *template, int type_argc, int slot)
 {
        int i;
        MonoRuntimeGenericContextOtherInfoTemplate *oti;
 
        g_assert (slot >= 0);
 
-       for (oti = template->other_infos, i = 0; i < slot; oti = oti->next, ++i) {
+       for (oti = get_other_info_templates (template, type_argc), i = 0; i < slot; oti = oti->next, ++i) {
                if (!oti)
                        return NULL;
        }
@@ -163,12 +214,12 @@ rgctx_template_get_other_slot (MonoRuntimeGenericContextTemplate *template, int
  * LOCKING: templates lock
  */
 static int
-rgctx_template_num_other_infos (MonoRuntimeGenericContextTemplate *template)
+rgctx_template_num_other_infos (MonoRuntimeGenericContextTemplate *template, int type_argc)
 {
        MonoRuntimeGenericContextOtherInfoTemplate *oti;
        int i;
 
-       for (i = 0, oti = template->other_infos; oti; ++i, oti = oti->next)
+       for (i = 0, oti = get_other_info_templates (template, type_argc); oti; ++i, oti = oti->next)
                ;
 
        return i;
@@ -346,22 +397,34 @@ alloc_oti (MonoImage *image)
        return mono_mempool_alloc0 (image->mempool, size);
 }
 
+#define MONO_RGCTX_SLOT_USED_MARKER    ((gpointer)&mono_defaults.object_class->byval_arg)
+
 /*
  * LOCKING: templates lock
  */
 static void
-rgctx_template_set_other_slot (MonoImage *image, MonoRuntimeGenericContextTemplate *template, int slot,
-       gpointer data, int info_type)
+rgctx_template_set_other_slot (MonoImage *image, MonoRuntimeGenericContextTemplate *template, int type_argc,
+       int slot, gpointer data, int info_type)
 {
+       static gboolean inited = FALSE;
+       static int num_markers = 0;
+       static int num_data = 0;
+
        int i;
-       MonoRuntimeGenericContextOtherInfoTemplate **oti;
+       MonoRuntimeGenericContextOtherInfoTemplate *list = get_other_info_templates (template, type_argc);
+       MonoRuntimeGenericContextOtherInfoTemplate **oti = &list;
+
+       if (!inited) {
+               mono_counters_register ("RGCTX oti num markers", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_markers);
+               mono_counters_register ("RGCTX oti num data", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_data);
+               inited = TRUE;
+       }
 
        g_assert (slot >= 0);
        g_assert (data);
 
        mono_loader_lock ();
 
-       oti = &template->other_infos;
        i = 0;
        while (i <= slot) {
                if (i > 0)
@@ -371,14 +434,37 @@ rgctx_template_set_other_slot (MonoImage *image, MonoRuntimeGenericContextTempla
                ++i;
        }
 
+       mono_loader_unlock ();
+
        g_assert (!(*oti)->data);
        (*oti)->data = data;
        (*oti)->info_type = info_type;
 
-       mono_loader_unlock ();
+       set_other_info_templates (template, type_argc, list);
+
+       if (data == MONO_RGCTX_SLOT_USED_MARKER)
+               ++num_markers;
+       else
+               ++num_data;
 }
 
-#define MONO_RGCTX_SLOT_USED_MARKER    ((gpointer)&mono_defaults.object_class->byval_arg)
+/*
+ * mono_method_get_declaring_generic_method:
+ * @method: an inflated method
+ *
+ * Returns an inflated method's declaring method.
+ */
+MonoMethod*
+mono_method_get_declaring_generic_method (MonoMethod *method)
+{
+       MonoMethodInflated *inflated;
+
+       g_assert (method->is_inflated);
+
+       inflated = (MonoMethodInflated*)method;
+
+       return inflated->declaring;
+}
 
 static gpointer
 inflate_other_data (gpointer data, int info_type, MonoGenericContext *context)
@@ -398,11 +484,17 @@ inflate_other_data (gpointer data, int info_type, MonoGenericContext *context)
                return mono_class_inflate_generic_type (data, context);
 
        case MONO_RGCTX_INFO_METHOD:
-       case MONO_RGCTX_INFO_GENERIC_METHOD_CODE: {
+       case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
+       case MONO_RGCTX_INFO_METHOD_RGCTX: {
                MonoMethod *method = data;
                MonoMethod *inflated_method;
+               MonoType *inflated_type = mono_class_inflate_generic_type (&method->klass->byval_arg, context);
+               MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
+
+               mono_class_init (inflated_class);
 
                if (method->wrapper_type != MONO_WRAPPER_NONE) {
+                       g_assert (info_type != MONO_RGCTX_INFO_METHOD_RGCTX);
                        g_assert (method->wrapper_type == MONO_WRAPPER_STATIC_RGCTX_INVOKE);
 
                        method = mono_marshal_method_from_wrapper (method);
@@ -412,6 +504,7 @@ inflate_other_data (gpointer data, int info_type, MonoGenericContext *context)
 
                inflated_method = mono_class_inflate_generic_method (method, context);
                mono_class_init (inflated_method->klass);
+               g_assert (inflated_method->klass == inflated_class);
                return inflated_method;
        }
 
@@ -440,7 +533,7 @@ inflate_other_info (MonoRuntimeGenericContextOtherInfoTemplate *oti, MonoGeneric
 }
 
 static MonoRuntimeGenericContextOtherInfoTemplate
-class_get_rgctx_template_oti (MonoClass *class, guint32 slot);
+class_get_rgctx_template_oti (MonoClass *class, int type_argc, guint32 slot);
 
 /*
  * mono_class_get_runtime_generic_context_template:
@@ -474,45 +567,52 @@ mono_class_get_runtime_generic_context_template (MonoClass *class)
        template = alloc_template (class);
        mono_loader_unlock ();
 
+       templates_lock ();
+
        if (class->parent) {
                if (class->parent->generic_class) {
                        guint32 num_entries;
+                       int max_argc, type_argc;
 
                        parent_template = mono_class_get_runtime_generic_context_template
                                (class->parent->generic_class->container_class);
-                       num_entries = rgctx_template_num_other_infos (parent_template);
 
-                       mono_loader_lock ();
+                       max_argc = template_get_max_argc (parent_template);
 
-                       /* FIXME: quadratic! */
-                       for (i = 0; i < num_entries; ++i) {
-                               MonoRuntimeGenericContextOtherInfoTemplate oti;
+                       for (type_argc = 0; type_argc <= max_argc; ++type_argc) {
+                               num_entries = rgctx_template_num_other_infos (parent_template, type_argc);
 
-                               oti = class_get_rgctx_template_oti (class->parent, i);
-                               if (oti.data && oti.data != MONO_RGCTX_SLOT_USED_MARKER)
-                                       rgctx_template_set_other_slot (class->image, template, i, oti.data, oti.info_type);
-                       }
+                               /* FIXME: quadratic! */
+                               for (i = 0; i < num_entries; ++i) {
+                                       MonoRuntimeGenericContextOtherInfoTemplate oti;
 
-                       mono_loader_unlock ();
+                                       oti = class_get_rgctx_template_oti (class->parent, type_argc, i);
+                                       if (oti.data && oti.data != MONO_RGCTX_SLOT_USED_MARKER) {
+                                               rgctx_template_set_other_slot (class->image, template, type_argc, i,
+                                                       oti.data, oti.info_type);
+                                       }
+                               }
+                       }
                } else {
                        MonoRuntimeGenericContextOtherInfoTemplate *oti;
+                       int max_argc, type_argc;
 
                        parent_template = mono_class_get_runtime_generic_context_template (class->parent);
 
-                       mono_loader_lock ();
+                       max_argc = template_get_max_argc (parent_template);
 
-                       /* FIXME: quadratic! */
-                       for (i = 0, oti = parent_template->other_infos; oti; ++i, oti = oti->next) {
-                               if (oti->data && oti->data != MONO_RGCTX_SLOT_USED_MARKER)
-                                       rgctx_template_set_other_slot (class->image, template, i, oti->data, oti->info_type);
+                       for (type_argc = 0; type_argc <= max_argc; ++type_argc) {
+                               /* FIXME: quadratic! */
+                               for (i = 0, oti = parent_template->other_infos; oti; ++i, oti = oti->next) {
+                                       if (oti->data && oti->data != MONO_RGCTX_SLOT_USED_MARKER) {
+                                               rgctx_template_set_other_slot (class->image, template, type_argc, i,
+                                                       oti->data, oti->info_type);
+                                       }
+                               }
                        }
-
-                       mono_loader_unlock ();
                }
        }
 
-       templates_lock ();
-
        if (class_lookup_rgctx_template (class)) {
                /* some other thread already set the template */
                template = class_lookup_rgctx_template (class);
@@ -529,12 +629,12 @@ mono_class_get_runtime_generic_context_template (MonoClass *class)
 }
 
 static MonoRuntimeGenericContextOtherInfoTemplate
-class_get_rgctx_template_oti (MonoClass *class, guint32 slot)
+class_get_rgctx_template_oti (MonoClass *class, int type_argc, guint32 slot)
 {
        if (class->generic_class) {
                MonoRuntimeGenericContextOtherInfoTemplate oti;
 
-               oti = class_get_rgctx_template_oti (class->generic_class->container_class, slot);
+               oti = class_get_rgctx_template_oti (class->generic_class->container_class, type_argc, slot);
                if (oti.data)
                        oti.data = inflate_other_info (&oti, &class->generic_class->context);
 
@@ -542,15 +642,10 @@ class_get_rgctx_template_oti (MonoClass *class, guint32 slot)
        } else {
                MonoRuntimeGenericContextTemplate *template;
                MonoRuntimeGenericContextOtherInfoTemplate *oti;
-               guint32 i;
 
                template = mono_class_get_runtime_generic_context_template (class);
-
-               for (i = 0, oti = template->other_infos; oti; ++i, oti = oti->next) {
-                       if (i == slot)
-                               break;
-               }
-               g_assert (i == slot && oti);
+               oti = rgctx_template_get_other_slot (template, type_argc, slot);
+               g_assert (oti);
 
                return *oti;
        }
@@ -609,6 +704,15 @@ instantiate_other_info (MonoDomain *domain, MonoRuntimeGenericContextOtherInfoTe
                return mono_compile_method (data);
        case MONO_RGCTX_INFO_CLASS_FIELD:
                return data;
+       case MONO_RGCTX_INFO_METHOD_RGCTX: {
+               MonoMethodInflated *method = data;
+
+               g_assert (method->method.method.is_inflated);
+               g_assert (method->context.method_inst);
+
+               return mono_method_lookup_rgctx (mono_class_vtable (domain, method->method.method.klass),
+                       method->context.method_inst);
+       }
        default:
                g_assert_not_reached ();
        }
@@ -618,7 +722,7 @@ instantiate_other_info (MonoDomain *domain, MonoRuntimeGenericContextOtherInfoTe
  * LOCKING: templates lock
  */
 static void
-fill_in_rgctx_template_slot (MonoClass *class, int index, gpointer data, int info_type)
+fill_in_rgctx_template_slot (MonoClass *class, int type_argc, int index, gpointer data, int info_type)
 {
        MonoRuntimeGenericContextTemplate *template = mono_class_get_runtime_generic_context_template (class);
        MonoClass *subclass;
@@ -627,9 +731,9 @@ fill_in_rgctx_template_slot (MonoClass *class, int index, gpointer data, int inf
 
        g_assert (!class->generic_class);
 
-       old_length = rgctx_template_num_other_infos (template);
-       rgctx_template_set_other_slot (class->image, template, index, data, info_type);
-       new_length = rgctx_template_num_other_infos (template);
+       old_length = rgctx_template_num_other_infos (template, type_argc);
+       rgctx_template_set_other_slot (class->image, template, type_argc, index, data, info_type);
+       new_length = rgctx_template_num_other_infos (template, type_argc);
 
        if (old_instances_length < 0)
                old_instances_length = old_length;
@@ -654,10 +758,10 @@ fill_in_rgctx_template_slot (MonoClass *class, int index, gpointer data, int inf
                g_assert (!subclass->generic_class);
                g_assert (subclass_template);
 
-               subclass_oti = class_get_rgctx_template_oti (subclass->parent, index);
+               subclass_oti = class_get_rgctx_template_oti (subclass->parent, type_argc, index);
                g_assert (subclass_oti.data);
 
-               fill_in_rgctx_template_slot (subclass, index, subclass_oti.data, info_type);
+               fill_in_rgctx_template_slot (subclass, type_argc, index, subclass_oti.data, info_type);
 
                subclass = subclass_template->next_subclass;
        }
@@ -667,16 +771,14 @@ fill_in_rgctx_template_slot (MonoClass *class, int index, gpointer data, int inf
  * LOCKING: templates lock
  */
 static int
-register_other_info (MonoClass *class, gpointer data, int info_type)
+register_other_info (MonoClass *class, int type_argc, gpointer data, int info_type)
 {
        int i;
        MonoRuntimeGenericContextTemplate *template = mono_class_get_runtime_generic_context_template (class);
        MonoClass *parent;
        MonoRuntimeGenericContextOtherInfoTemplate *oti;
 
-       g_assert (!class->generic_class && class->generic_container);
-
-       for (i = 0, oti = template->other_infos; oti; ++i, oti = oti->next) {
+       for (i = 0, oti = get_other_info_templates (template, type_argc); oti; ++i, oti = oti->next) {
                if (!oti->data)
                        break;
        }
@@ -694,19 +796,20 @@ register_other_info (MonoClass *class, gpointer data, int info_type)
                        parent = parent->generic_class->container_class;
 
                parent_template = mono_class_get_runtime_generic_context_template (parent);
-               oti = rgctx_template_get_other_slot (parent_template, i);
+               oti = rgctx_template_get_other_slot (parent_template, type_argc, i);
 
                if (oti && oti->data)
                        break;
 
-               rgctx_template_set_other_slot (parent->image, parent_template, i, MONO_RGCTX_SLOT_USED_MARKER, 0);
+               rgctx_template_set_other_slot (parent->image, parent_template, type_argc, i,
+                               MONO_RGCTX_SLOT_USED_MARKER, 0);
 
                parent = parent->parent;
        }
 
        /* Fill in the slot in this class and in all subclasses
           recursively. */
-       fill_in_rgctx_template_slot (class, i, data, info_type);
+       fill_in_rgctx_template_slot (class, type_argc, i, data, info_type);
 
        return i;
 }
@@ -724,25 +827,15 @@ other_info_equal (gpointer data1, gpointer data2, int info_type)
        case MONO_RGCTX_INFO_METHOD:
        case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
        case MONO_RGCTX_INFO_CLASS_FIELD:
+       case MONO_RGCTX_INFO_METHOD_RGCTX:
                return data1 == data2;
        default:
                g_assert_not_reached ();
        }
 }
 
-/*
- * mono_class_lookup_or_register_other_info:
- * @class: a class
- * @data: the info data
- * @info_type: the type of info to register about data
- * @generic_context: a generic context
- *
- * Looks up and, if necessary, adds information about other_class in
- * class's runtime generic context.  Returns the index of the
- * corresponding other-infos slot.
- */
-int
-mono_class_lookup_or_register_other_info (MonoClass *class, gpointer data, int info_type,
+static int
+lookup_or_register_other_info (MonoClass *class, int type_argc, gpointer data, int info_type,
        MonoGenericContext *generic_context)
 {
        static gboolean inited = FALSE;
@@ -753,11 +846,12 @@ mono_class_lookup_or_register_other_info (MonoClass *class, gpointer data, int i
        MonoRuntimeGenericContextOtherInfoTemplate *oti;
        int i;
 
-       g_assert (!class->generic_class && class->generic_container);
+       g_assert (!class->generic_class);
+       g_assert (class->generic_container || type_argc);
 
        templates_lock ();
 
-       for (oti = rgctx_template->other_infos, i = 0; oti; oti = oti->next, ++i) {
+       for (oti = get_other_info_templates (rgctx_template, type_argc), i = 0; oti; oti = oti->next, ++i) {
                gpointer inflated_data;
 
                if (!oti || oti->info_type != info_type || !oti->data)
@@ -771,7 +865,7 @@ mono_class_lookup_or_register_other_info (MonoClass *class, gpointer data, int i
                }
        }
 
-       i = register_other_info (class, data, info_type);
+       i = register_other_info (class, type_argc, data, info_type);
 
        templates_unlock ();
 
@@ -782,43 +876,155 @@ mono_class_lookup_or_register_other_info (MonoClass *class, gpointer data, int i
        if (i > max_slot)
                max_slot = i;
 
-
        return i;
 }
 
+/*
+ * mono_method_lookup_or_register_other_info:
+ * @method: a method
+ * @in_mrgctx: whether to put the data into the MRGCTX
+ * @data: the info data
+ * @info_type: the type of info to register about data
+ * @generic_context: a generic context
+ *
+ * Looks up and, if necessary, adds information about other_class in
+ * method's or method's class runtime generic context.  Returns the
+ * encoded slot number.
+ */
+guint32
+mono_method_lookup_or_register_other_info (MonoMethod *method, gboolean in_mrgctx, gpointer data,
+       int info_type, MonoGenericContext *generic_context)
+{
+       MonoClass *class = method->klass;
+       int type_argc, index;
+
+       if (in_mrgctx) {
+               MonoGenericInst *method_inst = mono_method_get_context (method)->method_inst;
+
+               g_assert (method->is_inflated && method_inst);
+               type_argc = method_inst->type_argc;
+               g_assert (type_argc > 0);
+       } else {
+               type_argc = 0;
+       }
+
+       index = lookup_or_register_other_info (class, type_argc, data, info_type, generic_context);
+
+       //g_print ("rgctx item at index %d argc %d\n", index, type_argc);
+
+       if (in_mrgctx)
+               return MONO_RGCTX_SLOT_MAKE_MRGCTX (index);
+       else
+               return MONO_RGCTX_SLOT_MAKE_RGCTX (index);
+}
+
 int
-mono_class_rgctx_get_array_size (int n)
+mono_class_rgctx_get_array_size (int n, gboolean mrgctx)
 {
        g_assert (n >= 0 && n < 30);
 
-       return 4 << n;
+       if (mrgctx)
+               return 6 << n;
+       else
+               return 4 << n;
 }
 
 /*
  * LOCKING: domain lock
  */
 static gpointer*
-alloc_rgctx_array (MonoDomain *domain, int n)
+alloc_rgctx_array (MonoDomain *domain, int n, gboolean is_mrgctx)
 {
        static gboolean inited = FALSE;
-       static int num_alloced = 0;
-       static int bytes_alloced = 0;
+       static int rgctx_num_alloced = 0;
+       static int rgctx_bytes_alloced = 0;
+       static int mrgctx_num_alloced = 0;
+       static int mrgctx_bytes_alloced = 0;
 
-       int size = mono_class_rgctx_get_array_size (n) * sizeof (gpointer);
+       int size = mono_class_rgctx_get_array_size (n, is_mrgctx) * sizeof (gpointer);
        gpointer array = mono_mempool_alloc0 (domain->mp, size);
 
        if (!inited) {
-               mono_counters_register ("RGCTX num arrays alloced", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_alloced);
-               mono_counters_register ("RGCTX bytes alloced", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &bytes_alloced);
+               mono_counters_register ("RGCTX num arrays alloced", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &rgctx_num_alloced);
+               mono_counters_register ("RGCTX bytes alloced", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &rgctx_bytes_alloced);
+               mono_counters_register ("MRGCTX num arrays alloced", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &mrgctx_num_alloced);
+               mono_counters_register ("MRGCTX bytes alloced", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &mrgctx_bytes_alloced);
                inited = TRUE;
        }
 
-       num_alloced++;
-       bytes_alloced += size;
+       if (is_mrgctx) {
+               mrgctx_num_alloced++;
+               mrgctx_bytes_alloced += size;
+       } else {
+               rgctx_num_alloced++;
+               rgctx_bytes_alloced += size;
+       }
 
        return array;
 }
 
+/*
+ * LOCKING: domain lock
+ */
+static gpointer
+fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContext *rgctx, guint32 slot,
+               MonoGenericInst *method_inst)
+{
+       gpointer info;
+       int i, first_slot, size;
+       MonoDomain *domain = class_vtable->domain;
+       MonoClass *class = class_vtable->klass;
+       MonoGenericContext *class_context = class->generic_class ? &class->generic_class->context : NULL;
+       MonoRuntimeGenericContextOtherInfoTemplate oti;
+       MonoGenericContext context = { class_context ? class_context->class_inst : NULL, method_inst };
+       int rgctx_index;
+
+       g_assert (rgctx);
+
+       /* First check whether that slot isn't already instantiated.
+          This might happen because lookup doesn't lock.  Allocate
+          arrays on the way. */
+       first_slot = 0;
+       size = mono_class_rgctx_get_array_size (0, method_inst != NULL);
+       if (method_inst)
+               size -= sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+       for (i = 0; ; ++i) {
+               int offset;
+
+               if (method_inst && i == 0)
+                       offset = sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+               else
+                       offset = 0;
+
+               if (slot < first_slot + size - 1) {
+                       rgctx_index = slot - first_slot + 1 + offset;
+                       info = rgctx [rgctx_index];
+                       if (info)
+                               return info;
+                       break;
+               }
+               if (!rgctx [offset + 0])
+                       rgctx [offset + 0] = alloc_rgctx_array (domain, i + 1, method_inst != NULL);
+               rgctx = rgctx [offset + 0];
+               first_slot += size - 1;
+               size = mono_class_rgctx_get_array_size (i + 1, method_inst != NULL);
+       }
+
+       g_assert (!rgctx [rgctx_index]);
+
+       oti = class_get_rgctx_template_oti (class_uninstantiated (class),
+                       method_inst ? method_inst->type_argc : 0, slot);
+
+       /*
+       if (method_inst)
+               g_print ("filling mrgctx slot %d table %d index %d\n", slot, i, rgctx_index);
+       */
+
+       info = rgctx [rgctx_index] = instantiate_other_info (domain, &oti, &context);
+
+       return info;
+}
+
 /*
  * mono_class_fill_runtime_generic_context:
  * @class_vtable: a vtable
@@ -832,12 +1038,8 @@ mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot)
        static gboolean inited = FALSE;
        static int num_alloced = 0;
 
-       MonoRuntimeGenericContext *rgctx;
        MonoDomain *domain = class_vtable->domain;
-       MonoClass *class = class_vtable->klass;
-       MonoGenericContext *context = &class->generic_class->context;
-       MonoRuntimeGenericContextOtherInfoTemplate oti;
-       int i, first_slot, size;
+       MonoRuntimeGenericContext *rgctx;
        gpointer info;
 
        mono_domain_lock (domain);
@@ -849,39 +1051,91 @@ mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot)
 
        rgctx = class_vtable->runtime_generic_context;
        if (!rgctx) {
-               rgctx = alloc_rgctx_array (domain, 0);
+               rgctx = alloc_rgctx_array (domain, 0, FALSE);
                class_vtable->runtime_generic_context = rgctx;
                num_alloced++;
        }
 
-       /* First check whether that slot isn't already instantiated.
-          This might happen because lookup doesn't lock.  Allocate
-          arrays on the way. */
-       first_slot = 0;
-       size = mono_class_rgctx_get_array_size (0);
-       for (i = 0; ; ++i) {
-               if (slot < first_slot + size - 1) {
-                       info = rgctx [slot - first_slot + 1];
-                       if (info) {
-                               mono_domain_unlock (domain);
-                               return info;
-                       }
-                       break;
-               }
-               if (!rgctx [0])
-                       rgctx [0] = alloc_rgctx_array (domain, i + 1);
-               rgctx = rgctx [0];
-               first_slot += size - 1;
-               size = mono_class_rgctx_get_array_size (i + 1);
-       }
+       info = fill_runtime_generic_context (class_vtable, rgctx, slot, 0);
 
-       g_assert (!rgctx [slot - first_slot + 1]);
+       mono_domain_unlock (domain);
 
-       oti = class_get_rgctx_template_oti (class_uninstantiated (class), slot);
+       return info;
+}
+
+gpointer
+mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot)
+{
+       MonoDomain *domain = mrgctx->class_vtable->domain;
+       gpointer info;
 
-       info = rgctx [slot - first_slot + 1] = instantiate_other_info (domain, &oti, context);
+       mono_domain_lock (domain);
+
+       info = fill_runtime_generic_context (mrgctx->class_vtable, (MonoRuntimeGenericContext*)mrgctx, slot,
+               mrgctx->method_inst);
 
        mono_domain_unlock (domain);
 
        return info;
 }
+
+static guint
+mrgctx_hash_func (gconstpointer key)
+{
+       const MonoMethodRuntimeGenericContext *mrgctx = key;
+
+       return mono_aligned_addr_hash (mrgctx->class_vtable) ^ mono_metadata_generic_inst_hash (mrgctx->method_inst);
+}
+
+static gboolean
+mrgctx_equal_func (gconstpointer a, gconstpointer b)
+{
+       const MonoMethodRuntimeGenericContext *mrgctx1 = a;
+       const MonoMethodRuntimeGenericContext *mrgctx2 = b;
+
+       return mrgctx1->class_vtable == mrgctx2->class_vtable &&
+               mono_metadata_generic_inst_equal (mrgctx1->method_inst, mrgctx2->method_inst);
+}
+
+MonoMethodRuntimeGenericContext*
+mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst)
+{
+       MonoDomain *domain = class_vtable->domain;
+       MonoMethodRuntimeGenericContext *mrgctx;
+       MonoMethodRuntimeGenericContext key;
+
+       g_assert (!class_vtable->klass->generic_container);
+       g_assert (!method_inst->is_open);
+
+       mono_domain_lock (domain);
+       if (!domain->method_rgctx_hash)
+               domain->method_rgctx_hash = g_hash_table_new (mrgctx_hash_func, mrgctx_equal_func);
+
+       key.class_vtable = class_vtable;
+       key.method_inst = method_inst;
+
+       mrgctx = g_hash_table_lookup (domain->method_rgctx_hash, &key);
+
+       if (!mrgctx) {
+               int i;
+
+               mrgctx = (MonoMethodRuntimeGenericContext*)alloc_rgctx_array (domain, 0, TRUE);
+               mrgctx->class_vtable = class_vtable;
+               mrgctx->method_inst = method_inst;
+
+               g_hash_table_insert (domain->method_rgctx_hash, mrgctx, mrgctx);
+
+               /*
+               g_print ("mrgctx alloced for %s <", mono_type_get_full_name (class_vtable->klass));
+               for (i = 0; i < method_inst->type_argc; ++i)
+                       g_print ("%s, ", mono_type_full_name (method_inst->type_argv [i]));
+               g_print (">\n");
+               */
+       }
+
+       mono_domain_unlock (domain);
+
+       g_assert (mrgctx);
+
+       return mrgctx;
+}
index bcbba56f3cec5a813f50a88aa6075a7327bc241b..b1bfc07d3b6a9bc0a1d8cc436f40539cc4de4cba 100644 (file)
@@ -468,6 +468,9 @@ mono_metadata_type_equal_full (MonoType *t1, MonoType *t2, gboolean signature_on
 MonoMarshalSpec *
 mono_metadata_parse_marshal_spec_with_mempool (MonoMemPool *mp, const char *ptr) MONO_INTERNAL;;
 
+guint         mono_metadata_generic_inst_hash (gconstpointer data) MONO_INTERNAL;
+gboolean       mono_metadata_generic_inst_equal (gconstpointer ka, gconstpointer kb) MONO_INTERNAL;
+
 void
 mono_metadata_field_info_with_mempool (MonoMemPool *mp, 
                                          MonoImage *meta, 
index 98312f2db9812634261d0564c7e8992dd4751c92..d49c3f8418612fc84f1c90fa3d5d1df012fabf73 100644 (file)
@@ -1401,8 +1401,8 @@ mono_type_equal (gconstpointer ka, gconstpointer kb)
        return 1;
 }
 
-static guint
-mono_generic_inst_hash (gconstpointer data)
+guint
+mono_metadata_generic_inst_hash (gconstpointer data)
 {
        const MonoGenericInst *ginst = (const MonoGenericInst *) data;
        guint hash = 0;
@@ -1437,8 +1437,8 @@ mono_generic_inst_equal_full (const MonoGenericInst *a, const MonoGenericInst *b
        return TRUE;
 }
 
-static gboolean
-mono_generic_inst_equal (gconstpointer ka, gconstpointer kb)
+gboolean
+mono_metadata_generic_inst_equal (gconstpointer ka, gconstpointer kb)
 {
        const MonoGenericInst *a = (const MonoGenericInst *) ka;
        const MonoGenericInst *b = (const MonoGenericInst *) kb;
@@ -1480,7 +1480,7 @@ mono_metadata_init (void)
        int i;
 
        type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
-       generic_inst_cache = g_hash_table_new_full (mono_generic_inst_hash, mono_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst);
+       generic_inst_cache = g_hash_table_new_full (mono_metadata_generic_inst_hash, mono_metadata_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst);
        generic_class_cache = g_hash_table_new_full (mono_generic_class_hash, mono_generic_class_equal, NULL, (GDestroyNotify)free_generic_class);
 
        for (i = 0; i < NBUILTIN_TYPES (); ++i)
index 43bdfee576951bb345bc6c131ee2b1b9b733d223..06e482ff311762715ef012b913a10e664dda948f 100644 (file)
@@ -1,3 +1,10 @@
+2008-06-13  Mark Probst  <mark.probst@gmail.com>
+
+       * mini.c, generic-sharing.c: Removed generic class relations.
+
+       * mini.c, tramp-amd64.c, tramp-x86.c: Additional arguments to
+       functions due to MRGCTX changes.
+
 2008-06-13  Mark Probst  <mark.probst@gmail.com>
 
        * inssel.brg, inssel-long.brg, inssel-long32.brg, mini-ops.h,
index 5721e4dfeed2adfabab92245d66cbd29f16e2940..b6643e71d8bce15fd1f8b0e71acc0b23c3850f1f 100644 (file)
@@ -14,9 +14,6 @@
 
 #include "mini.h"
 
-static int generic_class_lookups = 0;
-static int generic_class_lookup_failures = 0;
-
 /*
  * mini_method_get_context:
  * @method: a method
@@ -262,176 +259,6 @@ mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align)
        return mono_type_stack_size_internal (t, align, gsctx != NULL);
 }
 
-/*
- * mono_method_get_declaring_generic_method:
- * @method: an inflated method
- *
- * Returns an inflated method's declaring method.
- */
-MonoMethod*
-mono_method_get_declaring_generic_method (MonoMethod *method)
-{
-       MonoMethodInflated *inflated;
-
-       g_assert (method->is_inflated);
-
-       inflated = (MonoMethodInflated*)method;
-
-       return inflated->declaring;
-}
-
-/*
- * mono_class_generic_class_relation:
- * @klass: the class to be investigated
- * @method_klass: the reference class
- * @generic_context: the generic context of method_klass
- * @arg_num: where a value will be returned
- *
- * Discovers and returns the relation of klass with reference to
- * method_klass.  This can either be MINI_GENERIC_CLASS_RELATION_SELF,
- * meaning that klass is the same as method_klass,
- * MINI_GENERIC_CLASS_RELATION_ARGUMENT, meaning that klass is one of
- * the type arguments of method_klass, or otherwise
- * MINI_GENERIC_CLASS_RELATION_OTHER.  In the case of
- * MINI_GENERIC_CLASS_RELATION_ARGUMENT the number of the argument is
- * returned in *arg_num.
- */
-int
-mono_class_generic_class_relation (MonoClass *klass, int info_type, MonoClass *method_klass,
-       MonoGenericContext *generic_context, int *arg_num)
-{
-       int i = mono_class_lookup_or_register_other_info (method_klass, &klass->byval_arg, info_type, generic_context);
-
-       if (arg_num)
-               *arg_num = i;
-
-       return MINI_GENERIC_CLASS_RELATION_OTHER_TABLE;
-}
-
-typedef struct
-{
-       guint32 token;
-       MonoGenericContext *context;
-} MonoTokenAndContext;
-
-static guint
-token_context_hash (MonoTokenAndContext *tc)
-{
-       return (guint)((gulong)tc->token | (gulong)tc->context->class_inst | (gulong)tc->context->method_inst);
-}
-
-static gboolean
-token_context_equal (MonoTokenAndContext *tc1, MonoTokenAndContext *tc2)
-{
-       if (tc1->token != tc2->token)
-               return FALSE;
-
-       return tc1->context->class_inst == tc2->context->class_inst &&
-               tc1->context->method_inst == tc2->context->method_inst;
-}
-
-/*
- * mono_helper_get_rgctx_other_ptr:
- * @caller_class: the klass of the calling method
- * @vtable: the vtable with the runtime generic context
- * @token: the token which to look up
- * @token_source: what kind of item the token is for
- * @rgctx_type: the kind of value requested
- *
- * Is called from method to look up a token for a given runtime
- * generic sharing context and return some particular information
- * about the looked up class (the class itself, the vtable or the
- * static_data pointer).
- */
-gpointer
-mono_helper_get_rgctx_other_ptr (MonoClass *caller_class, MonoVTable *vtable,
-       guint32 token, guint32 token_source, guint32 rgctx_type, gint32 rgctx_index)
-{
-       MonoImage *image = caller_class->image;
-       MonoClass *klass = vtable->klass;
-       MonoClass *result = NULL;
-       MonoTokenAndContext tc = { token, &klass->generic_class->context };
-       gpointer result_ptr;
-
-       mono_loader_lock ();
-
-       generic_class_lookups++;
-
-       if (!image->generic_class_cache) {
-               image->generic_class_cache = g_hash_table_new ((GHashFunc)token_context_hash,
-                       (GCompareFunc)token_context_equal);
-       }
-
-       result = g_hash_table_lookup (image->generic_class_cache, &tc);
-
-       mono_loader_unlock ();
-
-       if (!result) {
-               generic_class_lookup_failures++;
-
-               switch (token_source) {
-               case MINI_TOKEN_SOURCE_FIELD: {
-                       MonoClassField *field = mono_field_from_token (image, token, &result, &klass->generic_class->context);
-
-                       g_assert (field);
-                       break;
-               }
-               case MINI_TOKEN_SOURCE_CLASS:
-                       result = mono_class_get_full (image, token, &klass->generic_class->context);
-                       break;
-               case MINI_TOKEN_SOURCE_METHOD: {
-                       MonoMethod *cmethod = mono_get_method_full (image, token, NULL,
-                               &klass->generic_class->context);
-                       result = cmethod->klass;
-                       break;
-               }
-               default :
-                       g_assert_not_reached ();
-               }
-
-               g_assert (result);
-
-               mono_class_init (result);
-
-               mono_loader_lock ();
-
-               /*
-                * In the meantime another thread might have put this class in
-                * the cache, so check again.
-                */
-               if (!g_hash_table_lookup (image->generic_class_cache, &tc)) {
-                       MonoTokenAndContext *tcp = (MonoTokenAndContext*) mono_mempool_alloc0 (image->mempool,
-                               sizeof (MonoTokenAndContext));
-
-                       *tcp = tc;
-
-                       g_hash_table_insert (image->generic_class_cache, tcp, result);
-               }
-
-               mono_loader_unlock ();
-       }
-
-       g_assert (result);
-
-       switch (rgctx_type) {
-       case MONO_RGCTX_INFO_KLASS:
-               result_ptr = result;
-               break;
-       case MONO_RGCTX_INFO_STATIC_DATA: {
-               MonoVTable *result_vtable = mono_class_vtable (vtable->domain, result);
-               result_ptr = result_vtable->data;
-               break;
-       }
-       case MONO_RGCTX_INFO_VTABLE:
-               result_ptr = mono_class_vtable (vtable->domain, result);
-               break;
-       default:
-               g_assert_not_reached ();
-       }
-
-       return result_ptr;
-}
-
 /*
  * mono_generic_sharing_init:
  *
@@ -440,8 +267,4 @@ mono_helper_get_rgctx_other_ptr (MonoClass *caller_class, MonoVTable *vtable,
 void
 mono_generic_sharing_init (void)
 {
-       mono_counters_register ("Generic class lookups", MONO_COUNTER_GENERICS | MONO_COUNTER_INT,
-                       &generic_class_lookups);
-       mono_counters_register ("Generic class lookup failures", MONO_COUNTER_GENERICS | MONO_COUNTER_INT,
-                       &generic_class_lookup_failures);
 }
index 6e4c3ce827a9f6469b068ae97409ae6d0edd5e6c..3e124da8948ceb3c3937c069935480cbbae1ccce 100644 (file)
@@ -4518,56 +4518,24 @@ get_runtime_generic_context_other_table_ptr (MonoCompile *cfg, MonoBasicBlock *b
        return field;
 }
 
-static MonoInst*
-get_runtime_generic_context_other_ptr (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *bblock,
-       MonoInst *rgc_ptr, guint32 token, int token_source, int rgctx_type, unsigned char *ip, int index)
-{
-       MonoInst *args [6];
-       int temp;
-       MonoInst *result;
-
-       g_assert (method->wrapper_type == MONO_WRAPPER_NONE);
-
-       NEW_CLASSCONST (cfg, args [0], method->klass);
-       args [1] = rgc_ptr;
-       NEW_ICONST (cfg, args [2], token);
-       NEW_ICONST (cfg, args [3], token_source);
-       NEW_ICONST (cfg, args [4], rgctx_type);
-       NEW_ICONST (cfg, args [5], index);
-
-       temp = mono_emit_jit_icall (cfg, bblock, mono_helper_get_rgctx_other_ptr, args, ip);
-       NEW_TEMPLOAD (cfg, result, temp);
-
-       return result;
-}
-
 static MonoInst*
 get_runtime_generic_context_ptr (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *bblock,
        MonoClass *klass, guint32 type_token, int token_source, MonoGenericContext *generic_context, MonoInst *rgctx,
        int rgctx_type, unsigned char *ip)
 {
-       int arg_num = -1;
-       int relation = mono_class_generic_class_relation (klass, rgctx_type, method->klass, generic_context, &arg_num);
+       guint32 slot = mono_method_lookup_or_register_other_info (method,
+               FALSE, &klass->byval_arg, rgctx_type, generic_context);
 
-       switch (relation) {
-       case MINI_GENERIC_CLASS_RELATION_OTHER_TABLE:
-               return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, arg_num, ip);
-       case MINI_GENERIC_CLASS_RELATION_OTHER:
-               return get_runtime_generic_context_other_ptr (cfg, method, bblock, rgctx,
-                       type_token, token_source, rgctx_type, ip, arg_num);
-       default:
-               g_assert_not_reached ();
-               return NULL;
-       }
+       return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, slot, ip);
 }
 
 static MonoInst*
 get_runtime_generic_context_method (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *bblock,
        MonoMethod *cmethod, MonoGenericContext *generic_context, MonoInst *rgctx, int rgctx_type, const unsigned char *ip)
 {
-       int arg_num = mono_class_lookup_or_register_other_info (method->klass, cmethod, rgctx_type, generic_context);
+       guint32 slot = mono_method_lookup_or_register_other_info (method, FALSE, cmethod, rgctx_type, generic_context);
 
-       return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, arg_num, ip);
+       return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, slot, ip);
 }
 
 static MonoInst*
@@ -4575,9 +4543,9 @@ get_runtime_generic_context_field (MonoCompile *cfg, MonoMethod *method, MonoBas
        MonoClassField *field, MonoGenericContext *generic_context, MonoInst *rgctx, int rgctx_type,
        const unsigned char *ip)
 {
-       int arg_num = mono_class_lookup_or_register_other_info (method->klass, field, rgctx_type, generic_context);
+       guint32 slot = mono_method_lookup_or_register_other_info (method, FALSE, field, rgctx_type, generic_context);
 
-       return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, arg_num, ip);
+       return get_runtime_generic_context_other_table_ptr (cfg, bblock, rgctx, slot, ip);
 }
 
 static gboolean
@@ -7460,7 +7428,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        MonoClassField *field;
                        gpointer addr = NULL;
                        gboolean shared_access = FALSE;
-                       int relation = 0;
 
                        CHECK_OPSIZE (5);
                        token = read32 (ip + 1);
@@ -7493,11 +7460,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                                klass->valuetype)
                                        GENERIC_SHARING_FAILURE (*ip);
 
-                               if (context_used) {
-                                       relation = mono_class_generic_class_relation (klass, MONO_RGCTX_INFO_VTABLE,
-                                               method->klass, generic_context, NULL);
+                               if (context_used)
                                        shared_access = TRUE;
-                               }
                        }
 
                        g_assert (!(field->type->attrs & FIELD_ATTRIBUTE_LITERAL));
@@ -13924,7 +13888,6 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_helper_ldstr_mscorlib, "helper_ldstr_mscorlib", "object int", FALSE);
        register_icall (mono_helper_newobj_mscorlib, "helper_newobj_mscorlib", "object int", FALSE);
        register_icall (mono_value_copy, "mono_value_copy", "void ptr ptr ptr", FALSE);
-       register_icall (mono_helper_get_rgctx_other_ptr, "get_rgctx_other_ptr", "ptr ptr ptr int32 int32 int32 int32", FALSE);
        register_icall (mono_object_castclass, "mono_object_castclass", "object object ptr", FALSE);
        register_icall (mono_break, "mono_break", NULL, TRUE);
        register_icall (mono_create_corlib_exception_0, "mono_create_corlib_exception_0", "object int", TRUE);
index 10223a7543b6ff7590a53294c7e9c452fb5a4e24..a6a6d7262174818543aa975003c44fe4f340e5a7 100644 (file)
@@ -512,7 +512,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
 
        index = slot;
        for (depth = 0; ; ++depth) {
-               int size = mono_class_rgctx_get_array_size (depth);
+               int size = mono_class_rgctx_get_array_size (depth, FALSE);
 
                if (index < size - 1)
                        break;
index 66bd0ee6dd13b810afd9fe883544a06118da0003..dc98dd0fc99f27aa6d6e646b2caa1582d378f8e7 100644 (file)
@@ -447,7 +447,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
 
        index = slot;
        for (depth = 0; ; ++depth) {
-               int size = mono_class_rgctx_get_array_size (depth);
+               int size = mono_class_rgctx_get_array_size (depth, FALSE);
 
                if (index < size - 1)
                        break;