Skip to content

Commit

Permalink
[mono] Miscellaneous startup optimizations (dotnet#101263)
Browse files Browse the repository at this point in the history
* Optimize out an unnecessary memset under g_slist_prepend
* Don't inline constructors of Exception or its descendants into interpreter method bodies
  • Loading branch information
kg authored and michaelgsharp committed May 8, 2024
1 parent f00fc0c commit 27a328a
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/mono/mono/eglib/gslist.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ g_slist_append (GSList *list, gpointer data)
GSList*
g_slist_prepend (GSList *list, gpointer data)
{
GSList *head = g_slist_alloc ();
// We don't need to zero the allocation using g_slist_alloc since we fully initialize the node
GSList *head = g_new (GSList, 1);
head->data = data;
head->next = list;

Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/metadata/class-getters.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ MONO_CLASS_GETTER(m_class_is_interfaces_inited, gboolean, , MonoClass, interface
MONO_CLASS_GETTER(m_class_is_simd_type, gboolean, , MonoClass, simd_type)
MONO_CLASS_GETTER(m_class_is_has_finalize_inited, gboolean, , MonoClass, has_finalize_inited)
MONO_CLASS_GETTER(m_class_is_fields_inited, gboolean, , MonoClass, fields_inited)
MONO_CLASS_GETTER(m_class_is_exception_class, gboolean, , MonoClass, is_exception_class)
MONO_CLASS_GETTER(m_class_has_failure, gboolean, , MonoClass, has_failure)
MONO_CLASS_GETTER(m_class_has_deferred_failure, gboolean, , MonoClass, has_deferred_failure)
MONO_CLASS_GETTER(m_class_has_weak_fields, gboolean, , MonoClass, has_weak_fields)
Expand Down
12 changes: 12 additions & 0 deletions src/mono/mono/metadata/class-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,17 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
}
}

// compute is_exception_class, used by interp to avoid inlining exception handling code
if (
klass->parent && !m_class_is_valuetype (klass) &&
!m_class_is_interface (klass)
) {
if (m_class_is_exception_class (klass->parent))
klass->is_exception_class = 1;
else if (!strcmp (klass->name, "Exception") && !strcmp(klass->name_space, "System"))
klass->is_exception_class = 1;
}

mono_loader_unlock ();

MONO_PROFILER_RAISE (class_loaded, (klass));
Expand Down Expand Up @@ -926,6 +937,7 @@ mono_class_create_generic_inst (MonoGenericClass *gclass)
klass->this_arg.byref__ = TRUE;
klass->is_inlinearray = gklass->is_inlinearray;
klass->inlinearray_value = gklass->inlinearray_value;
klass->is_exception_class = gklass->is_exception_class;
klass->enumtype = gklass->enumtype;
klass->valuetype = gklass->valuetype;

Expand Down
5 changes: 3 additions & 2 deletions src/mono/mono/metadata/class-private-definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ struct _MonoClass {
guint no_special_static_fields : 1; /* has no thread/context static fields */

guint nested_classes_inited : 1; /* Whenever nested_class is initialized */

/* next byte*/
guint interfaces_inited : 1; /* interfaces is initialized */
/* next byte*/
guint simd_type : 1; /* class is a simd intrinsic type */
guint has_finalize_inited : 1; /* has_finalize is initialized */
guint fields_inited : 1; /* setup_fields () has finished */
Expand All @@ -79,6 +78,8 @@ struct _MonoClass {
guint has_dim_conflicts : 1; /* Class has conflicting default interface methods */
guint any_field_has_auto_layout : 1; /* a field in this type's layout uses auto-layout */
guint has_deferred_failure : 1;
/* next byte*/
guint is_exception_class : 1; /* is System.Exception or derived from it */

MonoClass *parent;
MonoClass *nested_in;
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -2907,6 +2907,9 @@ interp_method_check_inlining (TransformData *td, MonoMethod *method, MonoMethodS
if (g_list_find (td->dont_inline, method))
return FALSE;

if (m_class_is_exception_class (method->klass) && !strcmp (method->name, ".ctor"))
return FALSE;

return TRUE;
}

Expand Down

0 comments on commit 27a328a

Please sign in to comment.