Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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
1 change: 1 addition & 0 deletions mono/metadata/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,7 @@ mono_image_close_except_pools (MonoImage *image)
}

free_hash (image->native_wrapper_cache);
free_hash (image->native_func_wrapper_cache);
free_hash (image->managed_wrapper_cache);
free_hash (image->delegate_begin_invoke_cache);
free_hash (image->delegate_end_invoke_cache);
Expand Down
62 changes: 36 additions & 26 deletions mono/metadata/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2993,34 +2993,34 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method)
typedef struct
{
MonoMethodSignature *sig;
MonoMethod *method;
} SignatureMethodPair;
gpointer pointer;
} SignaturePointerPair;

static guint
signature_method_pair_hash (gconstpointer data)
signature_pointer_pair_hash (gconstpointer data)
{
SignatureMethodPair *pair = (SignatureMethodPair*)data;
SignaturePointerPair *pair = (SignaturePointerPair*)data;

return mono_signature_hash (pair->sig) ^ mono_aligned_addr_hash (pair->method);
return mono_signature_hash (pair->sig) ^ mono_aligned_addr_hash (pair->pointer);
}

static gboolean
signature_method_pair_equal (SignatureMethodPair *pair1, SignatureMethodPair *pair2)
signature_pointer_pair_equal (gconstpointer data1, gconstpointer data2)
{
return mono_metadata_signature_equal (pair1->sig, pair2->sig) && (pair1->method == pair2->method);
SignaturePointerPair *pair1 = (SignaturePointerPair*) data1, *pair2 = (SignaturePointerPair*) data2;
return mono_metadata_signature_equal (pair1->sig, pair2->sig) && (pair1->pointer == pair2->pointer);
}

static gboolean
signature_method_pair_matches_method (gpointer key, gpointer value, gpointer user_data)
signature_pointer_pair_matches_pointer (gpointer key, gpointer value, gpointer user_data)
{
SignatureMethodPair *pair = (SignatureMethodPair*)key;
MonoMethod *method = (MonoMethod*)user_data;
SignaturePointerPair *pair = (SignaturePointerPair*)key;

return pair->method == method;
return pair->pointer == user_data;
}

static void
free_signature_method_pair (SignatureMethodPair *pair)
free_signature_pointer_pair (SignaturePointerPair *pair)
{
g_free (pair);
}
Expand All @@ -3034,8 +3034,8 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
MonoMethod *res;
GHashTable *cache;
gpointer cache_key = NULL;
SignatureMethodPair key;
SignatureMethodPair *new_key;
SignaturePointerPair key;
SignaturePointerPair *new_key;
int local_prev, local_target;
int pos0;
char *name;
Expand Down Expand Up @@ -3124,10 +3124,10 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
/* We need to cache the signature+method pair */
mono_marshal_lock ();
if (!*cache_ptr)
*cache_ptr = g_hash_table_new_full (signature_method_pair_hash, (GEqualFunc)signature_method_pair_equal, (GDestroyNotify)free_signature_method_pair, NULL);
*cache_ptr = g_hash_table_new_full (signature_pointer_pair_hash, (GEqualFunc)signature_pointer_pair_equal, (GDestroyNotify)free_signature_pointer_pair, NULL);
cache = *cache_ptr;
key.sig = invoke_sig;
key.method = target_method;
key.pointer = target_method;
res = g_hash_table_lookup (cache, &key);
mono_marshal_unlock ();
if (res)
Expand Down Expand Up @@ -3278,7 +3278,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
def = mono_mb_create_and_cache (cache, cache_key, mb, sig, sig->param_count + 16);
res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx);
} else if (callvirt) {
new_key = g_new0 (SignatureMethodPair, 1);
new_key = g_new0 (SignaturePointerPair, 1);
*new_key = key;

info = mono_wrapper_info_create (mb, subtype);
Expand Down Expand Up @@ -7368,13 +7368,18 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig
{
MonoMethodSignature *csig;

SignaturePointerPair key, *new_key;
MonoMethodBuilder *mb;
MonoMethod *res;
GHashTable *cache;
gboolean found;
char *name;

cache = get_cache (&image->native_wrapper_cache, mono_aligned_addr_hash, NULL);
if ((res = mono_marshal_find_in_cache (cache, func)))
key.sig = sig;
key.pointer = func;

cache = get_cache (&image->native_func_wrapper_cache, signature_pointer_pair_hash, signature_pointer_pair_equal);
if ((res = mono_marshal_find_in_cache (cache, &key)))
return res;

name = g_strdup_printf ("wrapper_native_%p", func);
Expand All @@ -7387,8 +7392,13 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig

csig = signature_dup (image, sig);
csig->pinvoke = 0;
res = mono_mb_create_and_cache (cache, func,
mb, csig, csig->param_count + 16);

new_key = g_new (SignaturePointerPair,1);
*new_key = key;
res = mono_mb_create_and_cache_full (cache, new_key, mb, csig, csig->param_count + 16, NULL, &found);
if (found)
g_free (new_key);

mono_mb_free (mb);

mono_marshal_set_wrapper_info (res, NULL);
Expand Down Expand Up @@ -11127,7 +11137,7 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method)
if (image->runtime_invoke_direct_cache)
g_hash_table_remove (image->runtime_invoke_direct_cache, method);
if (image->delegate_abstract_invoke_cache)
g_hash_table_foreach_remove (image->delegate_abstract_invoke_cache, signature_method_pair_matches_method, method);
g_hash_table_foreach_remove (image->delegate_abstract_invoke_cache, signature_pointer_pair_matches_pointer, method);
// FIXME: Need to clear the caches in other images as well
if (image->delegate_bound_static_invoke_cache)
g_hash_table_remove (image->delegate_bound_static_invoke_cache, mono_method_signature (method));
Expand All @@ -11137,9 +11147,9 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method)
}

static gboolean
signature_method_pair_matches_signature (gpointer key, gpointer value, gpointer user_data)
signature_pointer_pair_matches_signature (gpointer key, gpointer value, gpointer user_data)
{
SignatureMethodPair *pair = (SignatureMethodPair*)key;
SignaturePointerPair *pair = (SignaturePointerPair*)key;
MonoMethodSignature *sig = (MonoMethodSignature*)user_data;

return mono_metadata_signature_equal (pair->sig, sig);
Expand Down Expand Up @@ -11183,11 +11193,11 @@ mono_marshal_free_inflated_wrappers (MonoMethod *method)
g_hash_table_remove (method->klass->image->runtime_invoke_vtype_cache, sig);

/*
* indexed by SignatureMethodPair
* indexed by SignaturePointerPair
*/
if (sig && method->klass->image->delegate_abstract_invoke_cache)
g_hash_table_foreach_remove (method->klass->image->delegate_abstract_invoke_cache,
signature_method_pair_matches_signature, (gpointer)sig);
signature_pointer_pair_matches_signature, (gpointer)sig);

/*
* indexed by MonoMethod pointers
Expand Down
8 changes: 3 additions & 5 deletions mono/metadata/metadata-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,12 @@ struct _MonoImage {
GHashTable *runtime_invoke_vtype_cache;

/*
* indexed by SignatureMethodPair
* indexed by SignaturePointerPair
*/
GHashTable *delegate_abstract_invoke_cache;

/*
* indexed by SignatureMethodPair
*/
GHashTable *delegate_bound_static_invoke_cache;
GHashTable *native_func_wrapper_cache;

/*
* indexed by MonoMethod pointers
*/
Expand Down