From 7b246e6424922d1c51764ea7f715e43021b150c6 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 9 Apr 2024 17:17:05 -0700 Subject: [PATCH] Pre-compute and cache MonoClass name hash --- src/mono/mono/metadata/class-getters.h | 1 + src/mono/mono/metadata/class-init.c | 5 +++++ src/mono/mono/metadata/class-private-definition.h | 3 ++- src/mono/mono/metadata/metadata.c | 6 +++--- src/mono/mono/metadata/object.c | 2 +- src/mono/mono/mini/aot-compiler.c | 4 ++-- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/metadata/class-getters.h b/src/mono/mono/metadata/class-getters.h index eb69558a1d01b1..aa7f6a2034a65c 100644 --- a/src/mono/mono/metadata/class-getters.h +++ b/src/mono/mono/metadata/class-getters.h @@ -55,6 +55,7 @@ MONO_CLASS_GETTER(m_class_get_parent, MonoClass *, , MonoClass, parent) MONO_CLASS_GETTER(m_class_get_nested_in, MonoClass *, , MonoClass, nested_in) MONO_CLASS_GETTER(m_class_get_image, MonoImage *, , MonoClass, image) MONO_CLASS_GETTER(m_class_get_name, const char *, , MonoClass, name) +MONO_CLASS_GETTER(m_class_get_name_hash, guint, , MonoClass, name_hash) MONO_CLASS_GETTER(m_class_get_name_space, const char *, , MonoClass, name_space) MONO_CLASS_GETTER(m_class_get_type_token, guint32, , MonoClass, type_token) MONO_CLASS_GETTER(m_class_get_vtable_size, int, , MonoClass, vtable_size) diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index d9cfd751c8192e..c2210a0e41765c 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -500,6 +500,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError } klass->name = name; + klass->name_hash = mono_metadata_str_hash (name); klass->name_space = nspace; MONO_PROFILER_RAISE (class_loading, (klass)); @@ -909,6 +910,7 @@ mono_class_create_generic_inst (MonoGenericClass *gclass) } klass->name = gklass->name; + klass->name_hash = gklass->name_hash; klass->name_space = gklass->name_space; klass->image = gklass->image; @@ -1154,6 +1156,7 @@ mono_class_create_bounded_array (MonoClass *eclass, guint32 rank, gboolean bound name [nsize + maxrank + bounded] = ']'; name [nsize + maxrank + bounded + 1] = 0; klass->name = mm ? mono_mem_manager_strdup (mm, name) : mono_image_strdup (image, name); + klass->name_hash = mono_metadata_str_hash (klass->name); g_free (name); klass->type_token = 0; @@ -1508,6 +1511,7 @@ mono_class_create_ptr (MonoType *type) result->name_space = el_class->name_space; name = g_strdup_printf ("%s*", el_class->name); result->name = mm ? mono_mem_manager_strdup (mm, name) : mono_image_strdup (image, name); + result->name_hash = mono_metadata_str_hash (result->name); result->class_kind = MONO_CLASS_POINTER; g_free (name); @@ -1585,6 +1589,7 @@ mono_class_create_fnptr (MonoMethodSignature *sig) result->parent = NULL; /* no parent for PTR types */ result->name_space = "System"; result->name = "MonoFNPtrFakeClass"; + result->name_hash = mono_metadata_str_hash (result->name); result->class_kind = MONO_CLASS_POINTER; result->image = mono_defaults.corlib; /* need to fix... */ diff --git a/src/mono/mono/metadata/class-private-definition.h b/src/mono/mono/metadata/class-private-definition.h index 9beb3d40bad0f4..ff33e6dd8a78e6 100644 --- a/src/mono/mono/metadata/class-private-definition.h +++ b/src/mono/mono/metadata/class-private-definition.h @@ -99,7 +99,8 @@ struct _MonoClass { guint16 *interface_offsets_packed; guint8 *interface_bitmap; - gint32 inlinearray_value; /* System.Runtime.CompilerServices.InlineArrayAttribute length value */ + gint32 inlinearray_value; /* System.Runtime.CompilerServices.InlineArrayAttribute length value */ + guint name_hash; MonoClass **interfaces; diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index d005bfdb6b6b68..f837c66d9b471e 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -1931,7 +1931,7 @@ static guint mono_generic_class_hash (gconstpointer data) { const MonoGenericClass *gclass = (const MonoGenericClass *) data; - guint hash = mono_metadata_str_hash (m_class_get_name (gclass->container_class)); + guint hash = m_class_get_name_hash (gclass->container_class); hash *= 13; hash += gclass->is_tb_open; @@ -5611,8 +5611,8 @@ mono_metadata_type_hash (MonoType *t1) * inserted in a bunch of hash tables before been finished. */ if (image_is_dynamic (m_class_get_image (klass))) - return ((m_type_is_byref (t1) ? 1 : 0) << 6) | mono_metadata_str_hash (m_class_get_name (klass)); - return ((hash << 5) - hash) ^ mono_metadata_str_hash (m_class_get_name (klass)); + return ((m_type_is_byref (t1) ? 1 : 0) << 6) | m_class_get_name_hash (klass); + return ((hash << 5) - hash) ^ m_class_get_name_hash (klass); } case MONO_TYPE_PTR: return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type); diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 4b14d889b9df6b..2a0e9e9834e094 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -1343,7 +1343,7 @@ mono_method_get_imt_slot (MonoMethod *method) } /* Initialize hashes */ - hashes [0] = mono_metadata_str_hash (m_class_get_name (method->klass)); + hashes [0] = m_class_get_name_hash (method->klass); hashes [1] = mono_metadata_str_hash (m_class_get_name_space (method->klass)); hashes [2] = mono_metadata_str_hash (method->name); hashes [3] = mono_metadata_type_hash (sig->ret); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index bda04415e2d682..fdd8511f478744 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -11181,7 +11181,7 @@ mono_aot_type_hash (MonoType *t1) case MONO_TYPE_CLASS: case MONO_TYPE_SZARRAY: /* check if the distribution is good enough */ - return ((hash << 5) - hash) ^ mono_metadata_str_hash (m_class_get_name (t1->data.klass)); + return ((hash << 5) - hash) ^ m_class_get_name_hash (t1->data.klass); case MONO_TYPE_PTR: return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type); case MONO_TYPE_ARRAY: @@ -11251,7 +11251,7 @@ mono_aot_method_hash (MonoMethod *method) hashes [1] = 0; g_free (full_name); } else { - hashes [0] = mono_metadata_str_hash (m_class_get_name (klass)); + hashes [0] = m_class_get_name_hash (klass); hashes [1] = mono_metadata_str_hash (m_class_get_name_space (klass)); } if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE && mono_marshal_get_wrapper_info (method)->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER)