Skip to content

Commit 807562e

Browse files
authored
Pre-compute and cache MonoClass name hash (#100847)
During startup we spend a measurable amount of time hashing types, and some of that time is spent hashing classnames over and over again, so this PR caches the hash at class creation time instead.
1 parent 6b9381b commit 807562e

File tree

6 files changed

+14
-7
lines changed

6 files changed

+14
-7
lines changed

src/mono/mono/metadata/class-getters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ MONO_CLASS_GETTER(m_class_get_parent, MonoClass *, , MonoClass, parent)
5656
MONO_CLASS_GETTER(m_class_get_nested_in, MonoClass *, , MonoClass, nested_in)
5757
MONO_CLASS_GETTER(m_class_get_image, MonoImage *, , MonoClass, image)
5858
MONO_CLASS_GETTER(m_class_get_name, const char *, , MonoClass, name)
59+
MONO_CLASS_GETTER(m_class_get_name_hash, guint, , MonoClass, name_hash)
5960
MONO_CLASS_GETTER(m_class_get_name_space, const char *, , MonoClass, name_space)
6061
MONO_CLASS_GETTER(m_class_get_type_token, guint32, , MonoClass, type_token)
6162
MONO_CLASS_GETTER(m_class_get_vtable_size, int, , MonoClass, vtable_size)

src/mono/mono/metadata/class-init.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
500500
}
501501

502502
klass->name = name;
503+
klass->name_hash = mono_metadata_str_hash (name);
503504
klass->name_space = nspace;
504505

505506
MONO_PROFILER_RAISE (class_loading, (klass));
@@ -909,6 +910,7 @@ mono_class_create_generic_inst (MonoGenericClass *gclass)
909910
}
910911

911912
klass->name = gklass->name;
913+
klass->name_hash = gklass->name_hash;
912914
klass->name_space = gklass->name_space;
913915

914916
klass->image = gklass->image;
@@ -1154,6 +1156,7 @@ mono_class_create_bounded_array (MonoClass *eclass, guint32 rank, gboolean bound
11541156
name [nsize + maxrank + bounded] = ']';
11551157
name [nsize + maxrank + bounded + 1] = 0;
11561158
klass->name = mm ? mono_mem_manager_strdup (mm, name) : mono_image_strdup (image, name);
1159+
klass->name_hash = mono_metadata_str_hash (klass->name);
11571160
g_free (name);
11581161

11591162
klass->type_token = 0;
@@ -1508,6 +1511,7 @@ mono_class_create_ptr (MonoType *type)
15081511
result->name_space = el_class->name_space;
15091512
name = g_strdup_printf ("%s*", el_class->name);
15101513
result->name = mm ? mono_mem_manager_strdup (mm, name) : mono_image_strdup (image, name);
1514+
result->name_hash = mono_metadata_str_hash (result->name);
15111515
result->class_kind = MONO_CLASS_POINTER;
15121516
g_free (name);
15131517

@@ -1585,6 +1589,7 @@ mono_class_create_fnptr (MonoMethodSignature *sig)
15851589
result->parent = NULL; /* no parent for PTR types */
15861590
result->name_space = "System";
15871591
result->name = "MonoFNPtrFakeClass";
1592+
result->name_hash = mono_metadata_str_hash (result->name);
15881593
result->class_kind = MONO_CLASS_POINTER;
15891594

15901595
result->image = mono_defaults.corlib; /* need to fix... */

src/mono/mono/metadata/class-private-definition.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ struct _MonoClass {
9999
guint16 *interface_offsets_packed;
100100
guint8 *interface_bitmap;
101101

102-
gint32 inlinearray_value; /* System.Runtime.CompilerServices.InlineArrayAttribute length value */
102+
gint32 inlinearray_value; /* System.Runtime.CompilerServices.InlineArrayAttribute length value */
103+
guint name_hash;
103104

104105
MonoClass **interfaces;
105106

src/mono/mono/metadata/metadata.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,7 +1931,7 @@ static guint
19311931
mono_generic_class_hash (gconstpointer data)
19321932
{
19331933
const MonoGenericClass *gclass = (const MonoGenericClass *) data;
1934-
guint hash = mono_metadata_str_hash (m_class_get_name (gclass->container_class));
1934+
guint hash = m_class_get_name_hash (gclass->container_class);
19351935

19361936
hash *= 13;
19371937
hash += gclass->is_tb_open;
@@ -5611,8 +5611,8 @@ mono_metadata_type_hash (MonoType *t1)
56115611
* inserted in a bunch of hash tables before been finished.
56125612
*/
56135613
if (image_is_dynamic (m_class_get_image (klass)))
5614-
return ((m_type_is_byref (t1) ? 1 : 0) << 6) | mono_metadata_str_hash (m_class_get_name (klass));
5615-
return ((hash << 5) - hash) ^ mono_metadata_str_hash (m_class_get_name (klass));
5614+
return ((m_type_is_byref (t1) ? 1 : 0) << 6) | m_class_get_name_hash (klass);
5615+
return ((hash << 5) - hash) ^ m_class_get_name_hash (klass);
56165616
}
56175617
case MONO_TYPE_PTR:
56185618
return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type);

src/mono/mono/metadata/object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ mono_method_get_imt_slot (MonoMethod *method)
13431343
}
13441344

13451345
/* Initialize hashes */
1346-
hashes [0] = mono_metadata_str_hash (m_class_get_name (method->klass));
1346+
hashes [0] = m_class_get_name_hash (method->klass);
13471347
hashes [1] = mono_metadata_str_hash (m_class_get_name_space (method->klass));
13481348
hashes [2] = mono_metadata_str_hash (method->name);
13491349
hashes [3] = mono_metadata_type_hash (sig->ret);

src/mono/mono/mini/aot-compiler.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11181,7 +11181,7 @@ mono_aot_type_hash (MonoType *t1)
1118111181
case MONO_TYPE_CLASS:
1118211182
case MONO_TYPE_SZARRAY:
1118311183
/* check if the distribution is good enough */
11184-
return ((hash << 5) - hash) ^ mono_metadata_str_hash (m_class_get_name (t1->data.klass));
11184+
return ((hash << 5) - hash) ^ m_class_get_name_hash (t1->data.klass);
1118511185
case MONO_TYPE_PTR:
1118611186
return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type);
1118711187
case MONO_TYPE_ARRAY:
@@ -11251,7 +11251,7 @@ mono_aot_method_hash (MonoMethod *method)
1125111251
hashes [1] = 0;
1125211252
g_free (full_name);
1125311253
} else {
11254-
hashes [0] = mono_metadata_str_hash (m_class_get_name (klass));
11254+
hashes [0] = m_class_get_name_hash (klass);
1125511255
hashes [1] = mono_metadata_str_hash (m_class_get_name_space (klass));
1125611256
}
1125711257
if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE && mono_marshal_get_wrapper_info (method)->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER)

0 commit comments

Comments
 (0)