Skip to content

[mono] Fix more memory leaks in aot+interp mode. #89580

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 9 additions & 23 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,8 @@ mono_interp_get_imethod (MonoMethod *method)

sig = mono_method_signature_internal (method);

MonoMemPool *dyn_mp = NULL;
if (method->dynamic)
// FIXME: Use this in more places
dyn_mp = mono_mempool_new_size (sizeof (InterpMethod));

if (dyn_mp)
imethod = (InterpMethod*)mono_mempool_alloc0 (dyn_mp, sizeof (InterpMethod));
imethod = (InterpMethod*)mono_dyn_method_alloc0 (method, sizeof (InterpMethod));
else
imethod = (InterpMethod*)m_method_alloc0 (method, sizeof (InterpMethod));
imethod->method = method;
Expand All @@ -512,8 +507,8 @@ mono_interp_get_imethod (MonoMethod *method)
imethod->rtype = m_class_get_byval_arg (mono_defaults.string_class);
else
imethod->rtype = mini_get_underlying_type (sig->ret);
if (dyn_mp)
imethod->param_types = (MonoType**)mono_mempool_alloc0 (dyn_mp, sizeof (MonoType*) * sig->param_count);
if (method->dynamic)
imethod->param_types = (MonoType**)mono_dyn_method_alloc0 (method, sizeof (MonoType*) * sig->param_count);
else
imethod->param_types = (MonoType**)m_method_alloc0 (method, sizeof (MonoType*) * sig->param_count);
for (i = 0; i < sig->param_count; ++i)
Expand All @@ -523,11 +518,7 @@ mono_interp_get_imethod (MonoMethod *method)
InterpMethod *old_imethod;
if (!((old_imethod = mono_internal_hash_table_lookup (&jit_mm->interp_code_hash, method)))) {
mono_internal_hash_table_insert (&jit_mm->interp_code_hash, method, imethod);
if (method->dynamic)
((MonoDynamicMethod*)method)->mp = dyn_mp;
} else {
if (dyn_mp)
mono_mempool_destroy (dyn_mp);
imethod = old_imethod; /* leak the newly allocated InterpMethod to the mempool */
}
jit_mm_unlock (jit_mm);
Expand Down Expand Up @@ -1284,17 +1275,12 @@ compute_arg_offset (MonoMethodSignature *sig, int index)
}

static gpointer
imethod_alloc0 (InterpMethod *imethod, size_t size)
{
if (imethod->method->dynamic) {
MonoJitMemoryManager *jit_mm = get_default_jit_mm ();
jit_mm_lock (jit_mm);
gpointer ret = mono_mempool_alloc0 (((MonoDynamicMethod*)imethod->method)->mp, (guint)size);
jit_mm_unlock (jit_mm);
return ret;
} else {
return m_method_alloc0 (imethod->method, (guint)size);
}
imethod_alloc0 (InterpMethod *imethod, guint size)
{
if (imethod->method->dynamic)
return mono_dyn_method_alloc0 (imethod->method, size);
else
return m_method_alloc0 (imethod->method, size);
}

static guint32*
Expand Down
11 changes: 3 additions & 8 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,15 +1290,10 @@ interp_get_icall_sig (MonoMethodSignature *sig);
static gpointer
imethod_alloc0 (TransformData *td, size_t size)
{
if (td->rtm->method->dynamic) {
MonoJitMemoryManager *jit_mm = get_default_jit_mm ();
jit_mm_lock (jit_mm);
gpointer ret = mono_mempool_alloc0 (((MonoDynamicMethod*)td->rtm->method)->mp, (guint)size);
jit_mm_unlock (jit_mm);
return ret;
} else {
if (td->rtm->method->dynamic)
return mono_dyn_method_alloc0 (td->rtm->method, (guint)size);
else
return mono_mem_manager_alloc0 (td->mem_manager, (guint)size);
}
}

static void
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/mini/llvmonly-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ mini_llvmonly_create_ftndesc (MonoMethod *m, gpointer addr, gpointer arg)
{
MonoFtnDesc *ftndesc;

if (m->dynamic && ((MonoDynamicMethod*)m)->mp)
ftndesc = mono_mempool_alloc0 (((MonoDynamicMethod*)m)->mp, sizeof (MonoFtnDesc));
if (m->dynamic)
ftndesc = mono_dyn_method_alloc0 (m, sizeof (MonoFtnDesc));
else
ftndesc = (MonoFtnDesc*)m_method_alloc0 (m, sizeof (MonoFtnDesc));
ftndesc->addr = addr;
Expand Down
32 changes: 32 additions & 0 deletions src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -2950,6 +2950,21 @@ invalidated_delegate_trampoline (char *desc)
}
#endif

void *
mono_dyn_method_alloc0 (MonoMethod *method, guint size)
{
MonoDynamicMethod *dmethod = (MonoDynamicMethod*)method;

g_assert (method->dynamic);
MonoJitMemoryManager *jit_mm = get_default_jit_mm ();
jit_mm_lock (jit_mm);
if (!dmethod->mp)
dmethod->mp = mono_mempool_new_size (128);
gpointer ret = mono_mempool_alloc0 (dmethod->mp, size);
jit_mm_unlock (jit_mm);
return ret;
}

/*
* mono_jit_free_method:
*
Expand All @@ -2969,6 +2984,21 @@ mono_jit_free_method (MonoMethod *method)
if (mono_use_interpreter)
mini_get_interp_callbacks ()->free_method (method);

jit_mm = jit_mm_for_method (method);

jit_mm_lock (jit_mm);
if (jit_mm->dyn_delegate_info_hash) {
GSList *pairs = g_hash_table_lookup (jit_mm->dyn_delegate_info_hash, method);
for (GSList *l = pairs; l; l = l->next) {
MonoDelegateClassMethodPair *dpair = (MonoDelegateClassMethodPair *)l->data;
g_assert (dpair->method == method);
g_hash_table_remove (jit_mm->delegate_info_hash, dpair);
}
g_slist_free (pairs);
g_hash_table_remove (jit_mm->dyn_delegate_info_hash, method);
}
jit_mm_unlock (jit_mm);

ji = mono_dynamic_code_hash_lookup (method);
if (!ji)
return;
Expand Down Expand Up @@ -4399,6 +4429,8 @@ free_jit_mem_manager (MonoMemoryManager *mem_manager)
g_hash_table_destroy (info->jump_trampoline_hash);
g_hash_table_destroy (info->jit_trampoline_hash);
g_hash_table_destroy (info->delegate_info_hash);
if (info->dyn_delegate_info_hash)
g_hash_table_destroy (info->dyn_delegate_info_hash);
g_hash_table_destroy (info->static_rgctx_trampoline_hash);
g_hash_table_destroy (info->mrgctx_hash);
g_hash_table_destroy (info->interp_method_pointer_hash);
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/mini-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef struct {
GHashTable *jump_trampoline_hash;
GHashTable *jit_trampoline_hash;
GHashTable *delegate_info_hash;
GHashTable *dyn_delegate_info_hash;
/* Maps ClassMethodPair -> MonoDelegateTrampInfo */
GHashTable *static_rgctx_trampoline_hash;
/* maps MonoMethod -> MonoJitDynamicMethodInfo */
Expand Down Expand Up @@ -620,6 +621,7 @@ void mono_jit_dump_cleanup (void);
gpointer mini_alloc_generic_virtual_trampoline (MonoVTable *vtable, int size);
MonoException* mini_get_stack_overflow_ex (void);
MonoJitInfo* mini_alloc_jinfo (MonoJitMemoryManager *jit_mm, int size);
void* mono_dyn_method_alloc0 (MonoMethod *method, guint size);

/*
* Per-OS implementation functions.
Expand Down
22 changes: 20 additions & 2 deletions src/mono/mono/mini/mini-trampolines.c
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,11 @@ mono_create_delegate_trampoline_info (MonoClass *klass, MonoMethod *method, gboo
invoke = mono_get_delegate_invoke_internal (klass);
g_assert (invoke);

tramp_info = (MonoDelegateTrampInfo *)mono_mem_manager_alloc0 (jit_mm->mem_manager, sizeof (MonoDelegateTrampInfo));
if (method && method->dynamic)
// FIXME: Can the dynamic method outlive the delegate class if its unloadable ?
tramp_info = (MonoDelegateTrampInfo *)mono_dyn_method_alloc0 (method, sizeof (MonoDelegateTrampInfo));
else
tramp_info = (MonoDelegateTrampInfo *)mono_mem_manager_alloc0 (jit_mm->mem_manager, sizeof (MonoDelegateTrampInfo));
tramp_info->klass = klass;
tramp_info->invoke = invoke;
tramp_info->invoke_sig = mono_method_signature_internal (invoke);
Expand Down Expand Up @@ -1456,14 +1460,28 @@ mono_create_delegate_trampoline_info (MonoClass *klass, MonoMethod *method, gboo
}
#endif

dpair = (MonoDelegateClassMethodPair *)mono_mem_manager_alloc0 (jit_mm->mem_manager, sizeof (MonoDelegateClassMethodPair));
if (method && method->dynamic)
dpair = (MonoDelegateClassMethodPair *)mono_dyn_method_alloc0 (method, sizeof (MonoDelegateClassMethodPair));
else
dpair = (MonoDelegateClassMethodPair *)mono_mem_manager_alloc0 (jit_mm->mem_manager, sizeof (MonoDelegateClassMethodPair));
memcpy (dpair, &pair, sizeof (MonoDelegateClassMethodPair));

/* store trampoline address */
jit_mm_lock (jit_mm);
g_hash_table_insert (jit_mm->delegate_info_hash, dpair, tramp_info);
jit_mm_unlock (jit_mm);

if (method && method->dynamic) {
jit_mm = jit_mm_for_method (method);
jit_mm_lock (jit_mm);
if (!jit_mm->dyn_delegate_info_hash)
jit_mm->dyn_delegate_info_hash = g_hash_table_new (NULL, NULL);
GSList *l = g_hash_table_lookup (jit_mm->dyn_delegate_info_hash, method);
l = g_slist_prepend (l, dpair);
g_hash_table_insert (jit_mm->dyn_delegate_info_hash, method, l);
jit_mm_unlock (jit_mm);
}

return tramp_info;
}

Expand Down