Skip to content

Commit

Permalink
Merge pull request #1540 from esdrubal/marshallingcache
Browse files Browse the repository at this point in the history
[runtime] Added native_func_wrapper_cache.
  • Loading branch information
vargaz committed Jan 31, 2015
2 parents 910ebf9 + 09c48bc commit 3edd4ff
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 31 deletions.
1 change: 1 addition & 0 deletions mono/metadata/image.c
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
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
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

0 comments on commit 3edd4ff

Please sign in to comment.