2010-05-22 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 22 May 2010 20:53:01 +0000 (20:53 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 22 May 2010 20:53:01 +0000 (20:53 -0000)
* marshal.c (mono_marshal_get_generic_array_helper): Make these wrappers dynamic and
free them when their parent method is freed.

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

mono/metadata/ChangeLog
mono/metadata/image.c
mono/metadata/marshal.c
mono/metadata/metadata-internals.h

index 29d024198d98c59e6f982af0947431b372f279e4..397bda4c58bc9005e66d6b4734c3791c8937bae4 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-22  Zoltan Varga  <vargaz@gmail.com>
+
+       * marshal.c (mono_marshal_get_generic_array_helper): Make these wrappers dynamic and
+       free them when their parent method is freed.
+
 2010-05-22  Zoltan Varga  <vargaz@gmail.com>
 
        * metadata.c: Add a 'transient' argument to the MonoType creation functions, so
index 2cc90233f763338ea436238aec3274f134bdb605..3060f406c54257a698d060059f5d926ca8cda5f3 100644 (file)
@@ -1603,6 +1603,7 @@ 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->generic_array_helper_cache);
 
        /* The ownership of signatures is not well defined */
        //g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL);
index f2345572ce95818d0726145b990c17a44040e206..8bde7a8441d67ccad44a81663d1524136b0faa01 100644 (file)
@@ -164,14 +164,7 @@ register_icall (gpointer func, const char *name, const char *sigstr, gboolean sa
 static MonoMethodSignature*
 signature_dup (MonoImage *image, MonoMethodSignature *sig)
 {
-       MonoMethodSignature *res;
-       int sigsize;
-
-       res = mono_metadata_signature_alloc (image, sig->param_count);
-       sigsize = MONO_SIZEOF_METHOD_SIGNATURE + sig->param_count * sizeof (MonoType *);
-       memcpy (res, sig, sigsize);
-
-       return res;
+       return mono_metadata_signature_dup_full (image, sig);
 }
 
 MonoMethodSignature*
@@ -2283,13 +2276,15 @@ mono_marshal_need_free (MonoType *t, MonoMethodPInvoke *piinfo, MonoMarshalSpec
  * Return the hash table pointed to by VAR, lazily creating it if neccesary.
  */
 static GHashTable*
-get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func)
+get_cache_full (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func,
+                               GDestroyNotify  key_destroy_func,
+                               GDestroyNotify  value_destroy_func)
 {
        if (!(*var)) {
                mono_marshal_lock ();
                if (!(*var)) {
                        GHashTable *cache = 
-                               g_hash_table_new (hash_func, equal_func);
+                               g_hash_table_new_full (hash_func, equal_func, key_destroy_func, value_destroy_func);
                        mono_memory_barrier ();
                        *var = cache;
                }
@@ -2298,6 +2293,12 @@ get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func)
        return *var;
 }
 
+static GHashTable*
+get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func)
+{
+       return get_cache_full (var, hash_func, equal_func, NULL, NULL);
+}
+
 GHashTable*
 mono_marshal_get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func)
 {
@@ -4229,6 +4230,8 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual)
                g_free (tmp_sig);
        }
 
+       printf ("D: %s\n", mono_method_full_name (method, TRUE));
+
        /* to make it work with our special string constructors */
        if (!string_dummy) {
                MONO_GC_REGISTER_ROOT (string_dummy);
@@ -10834,15 +10837,22 @@ mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar
        MonoMethodBuilder *mb;
        MonoMethod *res;
        int i;
+       GHashTable *cache;
 
-       mb = mono_mb_new_no_dup_name (class, name, MONO_WRAPPER_MANAGED_TO_MANAGED);
+       cache = get_cache_full (&method->klass->image->generic_array_helper_cache, mono_aligned_addr_hash, NULL, NULL, (GDestroyNotify)mono_free_method);
+
+       if ((res = mono_marshal_find_in_cache (cache, method)))
+               return res;
+
+       mb = mono_mb_new (class, name, MONO_WRAPPER_MANAGED_TO_MANAGED);
        mb->method->slot = -1;
+       mb->dynamic = TRUE;
 
        mb->method->flags = METHOD_ATTRIBUTE_PRIVATE | METHOD_ATTRIBUTE_VIRTUAL |
                METHOD_ATTRIBUTE_NEW_SLOT | METHOD_ATTRIBUTE_HIDE_BY_SIG | METHOD_ATTRIBUTE_FINAL;
 
        sig = mono_method_signature (method);
-       csig = signature_dup (method->klass->image, sig);
+       csig = signature_dup (NULL, sig);
        csig->generic_param_count = 0;
 
        mono_mb_emit_ldarg (mb, 0);
@@ -10854,7 +10864,7 @@ mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface, gchar
        /* We can corlib internal methods */
        mb->skip_visibility = TRUE;
 
-       res = mono_mb_create_method (mb, csig, csig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, method, mb, csig, csig->param_count + 16);
 
        mono_mb_free (mb);
 
@@ -11157,6 +11167,8 @@ mono_marshal_free_inflated_wrappers (MonoMethod *method)
                g_hash_table_remove (method->klass->image->cominterop_wrapper_cache, method);
        if (method->klass->image->thunk_invoke_cache)
                g_hash_table_remove (method->klass->image->thunk_invoke_cache, method);
+       if (method->klass->image->generic_array_helper_cache)
+               g_hash_table_remove (method->klass->image->generic_array_helper_cache, method);
 
        mono_marshal_unlock ();
 }
index 9fa06f0446ca323c5198aec79510381af9866f3d..808dc27cd02ec81aa6db3b96673083d4ea96484c 100644 (file)
@@ -264,6 +264,7 @@ struct _MonoImage {
        GHashTable *cominterop_invoke_cache;
        GHashTable *cominterop_wrapper_cache; /* LOCKING: marshal lock */
        GHashTable *thunk_invoke_cache;
+       GHashTable *generic_array_helper_cache;
 
        /*
         * indexed by MonoClass pointers