diff options
-rw-r--r-- | mono/mini/mini-generic-sharing.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c index 45528b9cb45..90b19017a5b 100644 --- a/mono/mini/mini-generic-sharing.c +++ b/mono/mini/mini-generic-sharing.c @@ -2758,6 +2758,7 @@ mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type) * @method: a method * @in_mrgctx: whether to put the data into the MRGCTX * @data: the info data + * @did_register: whether data was registered * @info_type: the type of info to register about data * @generic_context: a generic context * @@ -2766,7 +2767,7 @@ mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type) * encoded slot number. */ static guint32 -lookup_or_register_info (MonoClass *klass, MonoMethod *method, gboolean in_mrgctx, gpointer data, +lookup_or_register_info (MonoClass *klass, MonoMethod *method, gboolean in_mrgctx, gpointer data, gboolean *did_register, MonoRgctxInfoType info_type, MonoGenericContext *generic_context) { int type_argc = 0; @@ -2815,7 +2816,10 @@ lookup_or_register_info (MonoClass *klass, MonoMethod *method, gboolean in_mrgct /* We haven't found the info */ if (index == -1) + { index = register_info (klass, type_argc, data, info_type); + *did_register = TRUE; + } /* interlocked by loader lock */ if (index > UnlockedRead (&rgctx_max_slot_number)) @@ -4145,6 +4149,8 @@ int mini_get_rgctx_entry_slot (MonoJumpInfoRgctxEntry *entry) { gpointer entry_data = NULL; + gboolean did_register = FALSE; + guint32 result = -1; switch (entry->data->type) { case MONO_PATCH_INFO_CLASS: @@ -4211,9 +4217,27 @@ mini_get_rgctx_entry_slot (MonoJumpInfoRgctxEntry *entry) } if (entry->in_mrgctx) - return lookup_or_register_info (entry->d.method->klass, entry->d.method, entry->in_mrgctx, entry_data, entry->info_type, mono_method_get_context (entry->d.method)); + result = lookup_or_register_info (entry->d.method->klass, entry->d.method, entry->in_mrgctx, entry_data, &did_register, entry->info_type, mono_method_get_context (entry->d.method)); else - return lookup_or_register_info (entry->d.klass, NULL, entry->in_mrgctx, entry_data, entry->info_type, mono_class_get_context (entry->d.klass)); + result = lookup_or_register_info (entry->d.klass, NULL, entry->in_mrgctx, entry_data, &did_register, entry->info_type, mono_class_get_context (entry->d.klass)); + + if (!did_register) + switch (entry->data->type) { + case MONO_PATCH_INFO_GSHAREDVT_CALL: + case MONO_PATCH_INFO_VIRT_METHOD: + case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE: + g_free (entry_data); + break; + case MONO_PATCH_INFO_GSHAREDVT_METHOD: { + g_free (((MonoGSharedVtMethodInfo *) entry_data)->entries); + g_free (entry_data); + break; + } + default : + break; + } + + return result; } static gboolean gsharedvt_supported; |