From 0593201d3a4d6dad78cef954dce801bec5791748 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 7 Mar 2025 17:43:50 -0800 Subject: [PATCH 1/2] Switch generic instance cache back to GHashTable --- src/mono/mono/metadata/loader-internals.h | 3 ++- src/mono/mono/metadata/memory-manager.c | 2 +- src/mono/mono/metadata/metadata.c | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) 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..b8f59e0766d56f 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -3496,10 +3496,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 +3512,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 (); From c7d30742a64d1e2584815b54e3bdb5cedecf7048 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 7 Mar 2025 16:19:44 -0800 Subject: [PATCH 2/2] Replace mono_metadata_generic_inst_hash with a MurmurHash3 variant --- src/mono/mono/metadata/metadata.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index b8f59e0766d56f..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