[mono] Allocate more memory for wrappers from mem managers if possible. (#52182)
authorZoltan Varga <vargaz@gmail.com>
Fri, 7 May 2021 20:08:23 +0000 (16:08 -0400)
committerGitHub <noreply@github.com>
Fri, 7 May 2021 20:08:23 +0000 (16:08 -0400)
* Allocate memory for wrappers from mem managers if possible.

Also unify the dynamic and non-dynamic cases a bit.

* Add mono_metadata_signature_dup_mem_manager () helper function.

* Free more wrapper data.

src/mono/mono/metadata/marshal.c
src/mono/mono/metadata/metadata-internals.h
src/mono/mono/metadata/metadata.c
src/mono/mono/metadata/method-builder-ilgen-internals.h
src/mono/mono/metadata/method-builder-ilgen.c
src/mono/mono/metadata/method-builder-internals.h

index e46a596..0fa1b9f 100644 (file)
@@ -1981,6 +1981,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
        MonoMethod *orig_method = method;
        WrapperInfo *info;
        WrapperSubtype subtype = WRAPPER_SUBTYPE_NONE;
+       MonoMemoryManager *mem_manager = NULL;
        gboolean found;
 
        g_assert (method && m_class_get_parent (method->klass) == mono_defaults.multicastdelegate_class &&
@@ -2091,8 +2092,12 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
                cache_key = sig;
        }
 
+       if (subtype == WRAPPER_SUBTYPE_NONE)
+               /* FIXME: Other subtypes */
+               mem_manager = m_method_get_mem_manager (method);
+
        if (!static_method_with_first_arg_bound) {
-               invoke_sig = mono_metadata_signature_dup_full (get_method_image (method), sig);
+               invoke_sig = mono_metadata_signature_dup_mem_manager (mem_manager, sig);
                invoke_sig->hasthis = 0;
        }
 
@@ -2109,6 +2114,11 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
        else
                mb = mono_mb_new (get_wrapper_target_class (get_method_image (method)), name, MONO_WRAPPER_DELEGATE_INVOKE);
        g_free (name);
+       mb->mem_manager = mem_manager;
+
+       if (subtype == WRAPPER_SUBTYPE_NONE)
+               /* FIXME: Other subtypes */
+               mb->mem_manager = m_method_get_mem_manager (method);
 
        get_marshal_cb ()->emit_delegate_invoke_internal (mb, sig, invoke_sig, static_method_with_first_arg_bound, callvirt, closed_over_null, method, target_method, target_class, ctx, container);
 
@@ -2384,6 +2394,7 @@ mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gbo
        char *name;
        const char *param_names [16];
        WrapperInfo *info;
+       MonoMemoryManager *mem_manager = NULL;
        MonoWrapperMethodCacheKey *method_key;
        MonoWrapperMethodCacheKey method_key_lookup_only;
        memset (&method_key_lookup_only, 0, sizeof (method_key_lookup_only));
@@ -2410,7 +2421,9 @@ mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gbo
        res = mono_marshal_find_in_cache (method_cache, method_key);
        if (res)
                return res;
-               
+
+       mem_manager = m_method_get_mem_manager (method);
+
        if (method->string_ctor) {
                callsig = lookup_string_ctor_signature (mono_method_signature_internal (method));
                if (!callsig)
@@ -2460,9 +2473,9 @@ mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gbo
                        return res;
                }
 
-               /* Make a copy of the signature from the image mempool */
+               /* Make a copy of the signature */
                tmp_sig = callsig;
-               callsig = mono_metadata_signature_dup_full (m_class_get_image (target_klass), callsig);
+               callsig = mono_metadata_signature_dup_mem_manager (mem_manager, callsig);
                g_free (tmp_sig);
        }
 
@@ -2488,6 +2501,7 @@ mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gbo
        name = mono_signature_to_name (callsig, virtual_ ? "runtime_invoke_virtual" : (need_direct_wrapper ? "runtime_invoke_direct" : "runtime_invoke"));
        mb = mono_mb_new (target_klass, name,  MONO_WRAPPER_RUNTIME_INVOKE);
        g_free (name);
+       mb->mem_manager = mem_manager;
 
        param_names [0] = "this";
        param_names [1] = "params";
@@ -2504,7 +2518,6 @@ mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gbo
                info = mono_wrapper_info_create (mb, virtual_ ? WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL : WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT);
                info->d.runtime_invoke.method = method;
                res = mono_mb_create_and_cache_full (method_cache, method_key, mb, csig, sig->param_count + 16, info, NULL);
-               ((MonoMethodWrapper*)res)->mem_manager = m_method_get_mem_manager (method);
        } else {
                MonoWrapperSignatureCacheKey *sig_key = g_new0 (MonoWrapperSignatureCacheKey, 1);
                sig_key->signature = callsig;
@@ -2522,7 +2535,6 @@ mono_marshal_get_runtime_invoke_full (MonoMethod *method, gboolean virtual_, gbo
                if (!res) {
                        MonoMethod *newm;
                        newm = mono_mb_create (mb, csig, sig->param_count + 16, info);
-                       ((MonoMethodWrapper*)newm)->mem_manager = m_method_get_mem_manager (method);
 
                        mono_marshal_lock ();
                        res = (MonoMethod *)g_hash_table_lookup (sig_cache, sig_key);
@@ -5762,12 +5774,13 @@ mono_marshal_get_generic_array_helper (MonoClass *klass, const gchar *name, Mono
 
        mb = mono_mb_new_no_dup_name (klass, name, MONO_WRAPPER_MANAGED_TO_MANAGED);
        mb->method->slot = -1;
+       mb->mem_manager = m_method_get_mem_manager (method);
 
        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_internal (method);
-       csig = mono_metadata_signature_dup_full (get_method_image (method), sig);
+       csig = mono_metadata_signature_dup_mem_manager (mb->mem_manager, sig);
        csig->generic_param_count = 0;
 
        get_marshal_cb ()->emit_generic_array_helper (mb, method, csig);
index 919abc4..1fb28e3 100644 (file)
@@ -996,6 +996,7 @@ MonoType *mono_metadata_type_dup_with_cmods (MonoImage *image, const MonoType *o
 
 MonoMethodSignature  *mono_metadata_signature_dup_full (MonoImage *image,MonoMethodSignature *sig);
 MonoMethodSignature  *mono_metadata_signature_dup_mempool (MonoMemPool *mp, MonoMethodSignature *sig);
+MonoMethodSignature  *mono_metadata_signature_dup_mem_manager (MonoMemoryManager *mem_manager, MonoMethodSignature *sig);
 MonoMethodSignature  *mono_metadata_signature_dup_add_this (MonoImage *image, MonoMethodSignature *sig, MonoClass *klass);
 
 MonoGenericInst *
index 0d9c7dc..5d10602 100644 (file)
@@ -56,7 +56,6 @@ static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1,
                                                    gboolean signature_only);
 static void free_generic_inst (MonoGenericInst *ginst);
 static void free_generic_class (MonoGenericClass *ginst);
-static void free_inflated_method (MonoMethodInflated *method);
 static void free_inflated_signature (MonoInflatedMethodSignature *sig);
 static void free_aggregate_modifiers (MonoAggregateModContainer *amods);
 static void mono_metadata_field_info_full (MonoImage *meta, guint32 index, guint32 *offset, guint32 *rva, MonoMarshalSpec **marshal_spec, gboolean alloc_from_image);
@@ -2375,7 +2374,8 @@ mono_metadata_signature_alloc (MonoImage *m, guint32 nparams)
 }
 
 static MonoMethodSignature*
-mono_metadata_signature_dup_internal_with_padding (MonoImage *image, MonoMemPool *mp, MonoMethodSignature *sig, size_t padding)
+mono_metadata_signature_dup_internal (MonoImage *image, MonoMemPool *mp, MonoMemoryManager *mem_manager,
+                                                                         MonoMethodSignature *sig, size_t padding)
 {
        int sigsize, sig_header_size;
        MonoMethodSignature *ret;
@@ -2387,6 +2387,8 @@ mono_metadata_signature_dup_internal_with_padding (MonoImage *image, MonoMemPool
                ret = (MonoMethodSignature *)mono_image_alloc (image, sigsize);
        } else if (mp) {
                ret = (MonoMethodSignature *)mono_mempool_alloc (mp, sigsize);
+       } else if (mem_manager) {
+               ret = (MonoMethodSignature *)mono_mem_manager_alloc (mem_manager, sigsize);
        } else {
                ret = (MonoMethodSignature *)g_malloc (sigsize);
        }
@@ -2404,11 +2406,6 @@ mono_metadata_signature_dup_internal_with_padding (MonoImage *image, MonoMemPool
        return ret;
 }
 
-static MonoMethodSignature*
-mono_metadata_signature_dup_internal (MonoImage *image, MonoMemPool *mp, MonoMethodSignature *sig)
-{
-       return mono_metadata_signature_dup_internal_with_padding (image, mp, sig, 0);
-}
 /*
  * signature_dup_add_this:
  *
@@ -2418,7 +2415,7 @@ MonoMethodSignature*
 mono_metadata_signature_dup_add_this (MonoImage *image, MonoMethodSignature *sig, MonoClass *klass)
 {
        MonoMethodSignature *ret;
-       ret = mono_metadata_signature_dup_internal_with_padding (image, NULL, sig, sizeof (MonoType *));
+       ret = mono_metadata_signature_dup_internal (image, NULL, NULL, sig, sizeof (MonoType *));
 
        ret->param_count = sig->param_count + 1;
        ret->hasthis = FALSE;
@@ -2434,15 +2431,13 @@ mono_metadata_signature_dup_add_this (MonoImage *image, MonoMethodSignature *sig
        return ret;
 }
 
-
-
 MonoMethodSignature*
 mono_metadata_signature_dup_full (MonoImage *image, MonoMethodSignature *sig)
 {
-       MonoMethodSignature *ret = mono_metadata_signature_dup_internal (image, NULL, sig);
+       MonoMethodSignature *ret = mono_metadata_signature_dup_internal (image, NULL, NULL, sig, 0);
 
        for (int i = 0 ; i < sig->param_count; i ++)
-               g_assert(ret->params [i]->type == sig->params [i]->type);
+               g_assert (ret->params [i]->type == sig->params [i]->type);
        g_assert (ret->ret->type == sig->ret->type);
 
        return ret;
@@ -2452,7 +2447,13 @@ mono_metadata_signature_dup_full (MonoImage *image, MonoMethodSignature *sig)
 MonoMethodSignature*
 mono_metadata_signature_dup_mempool (MonoMemPool *mp, MonoMethodSignature *sig)
 {
-       return mono_metadata_signature_dup_internal (NULL, mp, sig);
+       return mono_metadata_signature_dup_internal (NULL, mp, NULL, sig, 0);
+}
+
+MonoMethodSignature*
+mono_metadata_signature_dup_mem_manager (MonoMemoryManager *mem_manager, MonoMethodSignature *sig)
+{
+       return mono_metadata_signature_dup_internal (NULL, NULL, mem_manager, sig, 0);
 }
 
 /**
@@ -3176,20 +3177,6 @@ check_gmethod (gpointer key, gpointer value, gpointer data)
 }
 
 static void
-free_inflated_method (MonoMethodInflated *imethod)
-{
-       MonoMethod *method = (MonoMethod*)imethod;
-
-       if (method->signature)
-               mono_metadata_free_inflated_signature (method->signature);
-
-       if (method->wrapper_type)
-               g_free (((MonoMethodWrapper*)method)->method_data);
-
-       g_free (method);
-}
-
-static void
 free_generic_inst (MonoGenericInst *ginst)
 {
        int i;
index 642c490..1aa410b 100644 (file)
@@ -19,6 +19,7 @@ struct _MonoMethodBuilder {
        MonoMethod *method;
        gchar *name;
        gboolean no_dup_name;
+       MonoMemoryManager *mem_manager;
        GList *locals_list;
        gint locals;
        gboolean dynamic;
index 290d4f7..9d48b6d 100644 (file)
@@ -64,15 +64,36 @@ free_ilgen (MonoMethodBuilder *mb)
                g_free (l->data);
        }
        g_list_free (mb->locals_list);
-       if (!mb->dynamic) {
+       if (!mb->dynamic)
                g_free (mb->method);
-               if (!mb->no_dup_name)
-                       g_free (mb->name);
-               g_free (mb->code);
-       }
+       if (!mb->no_dup_name)
+               g_free (mb->name);
+       g_free (mb->code);
        g_free (mb);
 }
 
+static gpointer
+mb_alloc0 (MonoMethodBuilder *mb, int size)
+{
+       if (mb->dynamic)
+               return g_malloc0 (size);
+       else if (mb->mem_manager)
+               return mono_mem_manager_alloc0 (mb->mem_manager, size);
+       else
+               return mono_image_alloc0 (m_class_get_image (mb->method->klass), size);
+}
+
+static char*
+mb_strdup (MonoMethodBuilder *mb, const char *s)
+{
+       if (mb->dynamic)
+               return g_strdup (s);
+       else if (mb->mem_manager)
+               return mono_mem_manager_strdup (mb->mem_manager, s);
+       else
+               return mono_image_strdup (m_class_get_image (mb->method->klass), s);
+}
+
 static MonoMethod *
 create_method_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack)
 {
@@ -88,41 +109,34 @@ create_method_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *signature, int
        image = m_class_get_image (mb->method->klass);
 
        if (mb->dynamic) {
+               /* Allocated in reflection_methodbuilder_to_mono_method () */
                method = mb->method;
-               mw = (MonoMethodWrapper*)method;
-
-               method->name = mb->name;
-               method->dynamic = TRUE;
-
-               mw->header = header = (MonoMethodHeader *) 
-                       g_malloc0 (MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
-
-               header->code = mb->code;
-
-               for (i = 0, l = mb->locals_list; l; l = l->next, i++) {
-                       header->locals [i] = (MonoType*)l->data;
-               }
-       } else
-       {
-               /* Realloc the method info into a mempool */
-
-               method = (MonoMethod *)mono_image_alloc0 (image, sizeof (MonoMethodWrapper));
+       } else {
+               method = (MonoMethod *)mb_alloc0 (mb, sizeof (MonoMethodWrapper));
                memcpy (method, mb->method, sizeof (MonoMethodWrapper));
-               mw = (MonoMethodWrapper*) method;
-
-               if (mb->no_dup_name)
-                       method->name = mb->name;
-               else
-                       method->name = mono_image_strdup (image, mb->name);
-
-               mw->header = header = (MonoMethodHeader *) 
-                       mono_image_alloc0 (image, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
-
-               header->code = (const unsigned char *)mono_image_alloc (image, mb->pos);
-               memcpy ((char*)header->code, mb->code, mb->pos);
-
-               for (i = 0, l = mb->locals_list; l; l = l->next, i++) {
-                       header->locals [i] = (MonoType*)l->data;
+       }
+       mw = (MonoMethodWrapper*) method;
+       mw->mem_manager = mb->mem_manager;
+       if (mb->no_dup_name)
+               method->name = mb->name;
+       else
+               method->name = mb_strdup (mb, mb->name);
+       method->dynamic = mb->dynamic;
+       mw->header = header = (MonoMethodHeader *)
+               mb_alloc0 (mb, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
+       header->code = (const unsigned char *)mb_alloc0 (mb, mb->pos);
+       memcpy ((char*)header->code, mb->code, mb->pos);
+
+       for (i = 0, l = mb->locals_list; l; l = l->next, i++) {
+               MonoType *type = (MonoType*)l->data;
+               if (mb->mem_manager) {
+                       /* Allocated in mono_mb_add_local () */
+                       int size = mono_sizeof_type (type);
+                       header->locals [i] = mono_mem_manager_alloc0 (mb->mem_manager, size);
+                       memcpy (header->locals [i], type, size);
+                       g_free (type);
+               } else {
+                       header->locals [i] = type;
                }
        }
 
@@ -157,10 +171,7 @@ create_method_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *signature, int
                GList *tmp;
                void **data;
                l = g_list_reverse ((GList *)mw->method_data);
-               if (method_is_dynamic (method))
-                       data = (void **)g_malloc (sizeof (gpointer) * (i + 1));
-               else
-                       data = (void **)mono_image_alloc (image, sizeof (gpointer) * (i + 1));
+               data = (void **)mb_alloc0 (mb, sizeof (gpointer) * (i + 1));
                /* store the size in the first element */
                data [0] = GUINT_TO_POINTER (i);
                i = 1;
@@ -186,9 +197,11 @@ create_method_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *signature, int
 #endif
 
        if (mb->param_names) {
-               char **param_names = (char **)mono_image_alloc0 (image, signature->param_count * sizeof (gpointer));
+               char **param_names = (char **)mb_alloc0 (mb, signature->param_count * sizeof (gpointer));
                for (i = 0; i < signature->param_count; ++i)
-                       param_names [i] = mono_image_strdup (image, mb->param_names [i]);
+                       param_names [i] = mb_strdup (mb, mb->param_names [i]);
+
+               // FIXME: Mem managers
 
                mono_image_lock (image);
                if (!image->wrapper_param_names)
index c18c81f..3492864 100644 (file)
@@ -19,6 +19,7 @@ struct _MonoMethodBuilder {
        MonoMethod *method;
        gchar *name;
        gboolean no_dup_name;
+       MonoMemoryManager *mem_manager;
 };
 
 #endif