Make the var/mvar caches per-image, since the generic params they refer to can be...
authorZoltan Varga <vargaz@gmail.com>
Sun, 20 Feb 2011 00:52:48 +0000 (01:52 +0100)
committerZoltan Varga <vargaz@gmail.com>
Sun, 20 Feb 2011 00:52:48 +0000 (01:52 +0100)
mono/metadata/class.c
mono/metadata/image.c
mono/metadata/metadata-internals.h
mono/metadata/metadata.c

index 5c708747946c37e2f84718fd08e20454b2609805..fcfba2a5b9c05777896506e568daf5904f6d42d3 100644 (file)
@@ -5626,40 +5626,65 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
 }
 
 #define FAST_CACHE_SIZE 16
-static MonoClass *var_cache_fast [FAST_CACHE_SIZE];
-static MonoClass *mvar_cache_fast [FAST_CACHE_SIZE];
-static GHashTable *var_cache_slow;
-static GHashTable *mvar_cache_slow;
 
 static MonoClass *
 get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
 {
        int n = mono_generic_param_num (param);
+       MonoImage *image = param->image;
        GHashTable *ht;
 
-       if (n < FAST_CACHE_SIZE)
-               return (is_mvar ? mvar_cache_fast : var_cache_fast) [n];
-       ht = is_mvar ? mvar_cache_slow : var_cache_slow;
-       return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
+       g_assert (image);
+
+       if (n < FAST_CACHE_SIZE) {
+               if (is_mvar)
+                       return image->mvar_cache_fast ? image->mvar_cache_fast [n] : NULL;
+               else
+                       return image->var_cache_fast ? image->var_cache_fast [n] : NULL;
+       } else {
+               ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+               return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
+       }
 }
 
+/*
+ * LOCKING: Acquires the loader lock.
+ */
 static void
 set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
 {
        int n = mono_generic_param_num (param);
+       MonoImage *image = param->image;
        GHashTable *ht;
 
+       g_assert (image);
+
        if (n < FAST_CACHE_SIZE) {
-               (is_mvar ? mvar_cache_fast : var_cache_fast) [n] = klass;
+               if (is_mvar) {
+                       /* No locking needed */
+                       if (!image->mvar_cache_fast)
+                               image->mvar_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
+                       image->mvar_cache_fast [n] = klass;
+               } else {
+                       if (!image->var_cache_fast)
+                               image->var_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
+                       image->var_cache_fast [n] = klass;
+               }
                return;
        }
-       ht = is_mvar ? mvar_cache_slow : var_cache_slow;
+       ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
        if (!ht) {
-               ht = g_hash_table_new (NULL, NULL);
-               if (is_mvar)
-                       mvar_cache_slow = ht;
-               else
-                       var_cache_slow = ht;
+               mono_loader_lock ();
+               ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+               if (!ht) {
+                       ht = g_hash_table_new (NULL, NULL);
+                       mono_memory_barrier ();
+                       if (is_mvar)
+                               image->mvar_cache_slow = ht;
+                       else
+                               image->var_cache_slow = ht;
+               }
+               mono_loader_unlock ();
        }
 
        g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
index b9d7d7b8facf0e314aa710541bd489f01846d7e5..5d098a03b04c4cca256cbeaf9e50a328d2d1991f 100644 (file)
@@ -1625,6 +1625,8 @@ mono_image_close_except_pools (MonoImage *image)
        free_hash (image->castclass_cache);
        free_hash (image->proxy_isinst_cache);
        free_hash (image->thunk_invoke_cache);
+       free_hash (image->var_cache_slow);
+       free_hash (image->mvar_cache_slow);
 
        /* The ownership of signatures is not well defined */
        //g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL);
index 40f65d0e96b2764d972523106f74d83edc7c02fe..4a4ff17e5e81a7433469f1b2c9681085062e66ae 100644 (file)
@@ -314,6 +314,12 @@ struct _MonoImage {
        /* List of image sets containing this image */
        GSList *image_sets;
 
+       /* Caches for MonoClass-es representing anon generic params */
+       MonoClass **var_cache_fast;
+       MonoClass **mvar_cache_fast;
+       GHashTable *var_cache_slow;
+       GHashTable *mvar_cache_slow;
+
        /*
         * No other runtime locks must be taken while holding this lock.
         * It's meant to be used only to mutate and query structures part of this image.
index 3d872b2e6280290e4a4eecf2b043429701f19020..40755496fc510abe09f54a94b00ebece95b9c88d 100644 (file)
@@ -10,9 +10,6 @@
  */
 
 #include <config.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -2795,10 +2792,8 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
                        break;
        is_open = (i < type_argc);
 
-       ginst = alloca (size);
-#ifndef MONO_SMALL_CONFIG
-       ginst->id = 0;
-#endif
+       ginst = g_alloca (size);
+       memset (ginst, 0, sizeof (MonoGenericInst));
        ginst->is_open = is_open;
        ginst->type_argc = type_argc;
        memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *));