diff --git a/src/mono/mono/metadata/loader-internals.h b/src/mono/mono/metadata/loader-internals.h index 60d39ff6a6398c..c9a340f928b7b2 100644 --- a/src/mono/mono/metadata/loader-internals.h +++ b/src/mono/mono/metadata/loader-internals.h @@ -175,7 +175,8 @@ struct _MonoMemoryManager { MonoAssemblyLoadContext **alcs; // Generic-specific caches - dn_simdhash_ght_t *ginst_cache, *gmethod_cache, *gsignature_cache; + GHashTable *ginst_cache; + dn_simdhash_ght_t *gmethod_cache, *gsignature_cache; MonoConcurrentHashTable *gclass_cache; /* mirror caches of ones already on MonoImage. These ones contain generics */ diff --git a/src/mono/mono/metadata/memory-manager.c b/src/mono/mono/metadata/memory-manager.c index edb7fff24a8d3c..e7a234661db5a3 100644 --- a/src/mono/mono/metadata/memory-manager.c +++ b/src/mono/mono/metadata/memory-manager.c @@ -238,7 +238,7 @@ memory_manager_delete (MonoMemoryManager *memory_manager, gboolean debug_unload) MonoMemoryManager *mm = memory_manager; if (mm->gclass_cache) mono_conc_hashtable_destroy (mm->gclass_cache); - free_simdhash (&mm->ginst_cache); + free_hash (&mm->ginst_cache); free_simdhash (&mm->gmethod_cache); free_simdhash (&mm->gsignature_cache); free_hash (&mm->szarray_cache); diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index d194af42eacdc9..1c34800cdb8676 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -38,6 +38,7 @@ #include #include #include +#include "../native/containers/dn-simdhash-utils.h" /* Auxiliary structure used for caching inflated signatures */ typedef struct { @@ -1874,18 +1875,21 @@ mono_type_equal (gconstpointer ka, gconstpointer kb) guint mono_metadata_generic_inst_hash (gconstpointer data) { + // Custom MurmurHash3 for generic instances to produce a high quality hash const MonoGenericInst *ginst = (const MonoGenericInst *) data; - guint hash = 0; g_assert (ginst); g_assert (ginst->type_argv); + uint32_t h1 = ginst->type_argc; + for (guint i = 0; i < ginst->type_argc; ++i) { - hash *= 13; g_assert (ginst->type_argv [i]); - hash += mono_metadata_type_hash (ginst->type_argv [i]); + MURMUR3_HASH_BLOCK ((uint32_t) mono_metadata_type_hash (ginst->type_argv [i])); } - return hash ^ (ginst->is_open << 8); + h1 ^= ginst->is_open; + + return (guint)murmur3_fmix32 (h1); } static gboolean @@ -3496,10 +3500,9 @@ mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate) mono_loader_lock (); if (!mm->ginst_cache) - mm->ginst_cache = dn_simdhash_ght_new_full (mono_metadata_generic_inst_hash, mono_metadata_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst, 0, NULL); + mm->ginst_cache = g_hash_table_new_full (mono_metadata_generic_inst_hash, mono_metadata_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst); - MonoGenericInst *ginst = NULL; - dn_simdhash_ght_try_get_value (mm->ginst_cache, candidate, (void **)&ginst); + MonoGenericInst *ginst = g_hash_table_lookup (mm->ginst_cache, candidate); if (!ginst) { int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *); ginst = (MonoGenericInst *)mono_mem_manager_alloc0 (mm, size); @@ -3513,7 +3516,7 @@ mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate) for (int i = 0; i < type_argc; ++i) ginst->type_argv [i] = mono_metadata_type_dup (NULL, candidate->type_argv [i]); - dn_simdhash_ght_insert (mm->ginst_cache, ginst, ginst); + g_hash_table_insert (mm->ginst_cache, ginst, ginst); } mono_loader_unlock ();