Skip to content

Commit b46e5a2

Browse files
[release/9.0-staging] [mono] Switch generic instance cache back to GHashTable; improve ginst hash function (#113316)
Backport of #113287 This change will revert to the hashtable container used for the generic instance cache in .NET 8.0 to address a performance regression introduced by changing to a different container in 9. Also improves the hash function used for the cache (the existing one was suboptimal.) Co-authored-by: Katelyn Gadd <[email protected]>
1 parent 8670c12 commit b46e5a2

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

src/mono/mono/metadata/loader-internals.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ struct _MonoMemoryManager {
175175
MonoAssemblyLoadContext **alcs;
176176

177177
// Generic-specific caches
178-
dn_simdhash_ght_t *ginst_cache, *gmethod_cache, *gsignature_cache;
178+
GHashTable *ginst_cache;
179+
dn_simdhash_ght_t *gmethod_cache, *gsignature_cache;
179180
MonoConcurrentHashTable *gclass_cache;
180181

181182
/* mirror caches of ones already on MonoImage. These ones contain generics */

src/mono/mono/metadata/memory-manager.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ memory_manager_delete (MonoMemoryManager *memory_manager, gboolean debug_unload)
238238
MonoMemoryManager *mm = memory_manager;
239239
if (mm->gclass_cache)
240240
mono_conc_hashtable_destroy (mm->gclass_cache);
241-
free_simdhash (&mm->ginst_cache);
241+
free_hash (&mm->ginst_cache);
242242
free_simdhash (&mm->gmethod_cache);
243243
free_simdhash (&mm->gsignature_cache);
244244
free_hash (&mm->szarray_cache);

src/mono/mono/metadata/metadata.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <mono/utils/atomic.h>
3939
#include <mono/utils/unlocked.h>
4040
#include <mono/utils/mono-logger-internals.h>
41+
#include "../native/containers/dn-simdhash-utils.h"
4142

4243
/* Auxiliary structure used for caching inflated signatures */
4344
typedef struct {
@@ -1874,18 +1875,21 @@ mono_type_equal (gconstpointer ka, gconstpointer kb)
18741875
guint
18751876
mono_metadata_generic_inst_hash (gconstpointer data)
18761877
{
1878+
// Custom MurmurHash3 for generic instances to produce a high quality hash
18771879
const MonoGenericInst *ginst = (const MonoGenericInst *) data;
1878-
guint hash = 0;
18791880
g_assert (ginst);
18801881
g_assert (ginst->type_argv);
18811882

1883+
uint32_t h1 = ginst->type_argc;
1884+
18821885
for (guint i = 0; i < ginst->type_argc; ++i) {
1883-
hash *= 13;
18841886
g_assert (ginst->type_argv [i]);
1885-
hash += mono_metadata_type_hash (ginst->type_argv [i]);
1887+
MURMUR3_HASH_BLOCK ((uint32_t) mono_metadata_type_hash (ginst->type_argv [i]));
18861888
}
18871889

1888-
return hash ^ (ginst->is_open << 8);
1890+
h1 ^= ginst->is_open;
1891+
1892+
return (guint)murmur3_fmix32 (h1);
18891893
}
18901894

18911895
static gboolean
@@ -3494,10 +3498,9 @@ mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate)
34943498
mono_loader_lock ();
34953499

34963500
if (!mm->ginst_cache)
3497-
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);
3501+
mm->ginst_cache = g_hash_table_new_full (mono_metadata_generic_inst_hash, mono_metadata_generic_inst_equal, NULL, (GDestroyNotify)free_generic_inst);
34983502

3499-
MonoGenericInst *ginst = NULL;
3500-
dn_simdhash_ght_try_get_value (mm->ginst_cache, candidate, (void **)&ginst);
3503+
MonoGenericInst *ginst = g_hash_table_lookup (mm->ginst_cache, candidate);
35013504
if (!ginst) {
35023505
int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
35033506
ginst = (MonoGenericInst *)mono_mem_manager_alloc0 (mm, size);
@@ -3511,7 +3514,7 @@ mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate)
35113514
for (int i = 0; i < type_argc; ++i)
35123515
ginst->type_argv [i] = mono_metadata_type_dup (NULL, candidate->type_argv [i]);
35133516

3514-
dn_simdhash_ght_insert (mm->ginst_cache, ginst, ginst);
3517+
g_hash_table_insert (mm->ginst_cache, ginst, ginst);
35153518
}
35163519

35173520
mono_loader_unlock ();

0 commit comments

Comments
 (0)