From 77ee77cd250ae38f29eef0ebf80890b117768bea Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 14 Jan 2022 16:03:44 -0500 Subject: [PATCH] [mono] Disable partial generic sharing for gparams with non-enum constraints for method gparams too. This is an optimization, but it also avoids hitting some gsharing limitations wrt calling abstract static methods from gshared code. Fixes https://github.com/dotnet/runtime/issues/60447. --- src/mono/mono/mini/mini-generic-sharing.c | 28 +++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 449cf376fbaea3..f05a78aa8d804a 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -3521,19 +3521,29 @@ mono_method_is_generic_sharable_full (MonoMethod *method, gboolean allow_type_va if (method->is_inflated) { MonoMethodInflated *inflated = (MonoMethodInflated*)method; - MonoGenericContext *context = &inflated->context; + MonoGenericContext *ctx = &inflated->context; - if (!mono_generic_context_is_sharable_full (context, allow_type_vars, allow_partial)) + if (!mono_generic_context_is_sharable_full (ctx, allow_type_vars, allow_partial)) return FALSE; g_assert (inflated->declaring); -#if 0 - if (inflated->declaring->is_generic) { - if (has_constraints (mono_method_get_generic_container (inflated->declaring))) { + /* + * If all the parameters are primitive types and constraints prevent + * them from being instantiated with enums, then only the primitive + * type instantiation is possible, thus sharing is not useful. + * Happens with generic math interfaces. + */ + if ((!ctx->class_inst || is_primitive_inst (ctx->class_inst)) && + (!ctx->method_inst || is_primitive_inst (ctx->method_inst))) { + MonoGenericContainer *container = mono_method_get_generic_container (inflated->declaring); + if (container && has_constraints (container)) { + for (int i = 0; i < container->type_argc; ++i) { + if (!gparam_can_be_enum (&container->type_params [i])) + return FALSE; + } } } -#endif } if (mono_class_is_ginst (method->klass)) { @@ -3544,12 +3554,6 @@ mono_method_is_generic_sharable_full (MonoMethod *method, gboolean allow_type_va g_assert (mono_class_get_generic_class (method->klass)->container_class && mono_class_is_gtd (mono_class_get_generic_class (method->klass)->container_class)); - /* - * If all the parameters are primitive types and constraints prevent - * them from being instantiated with enums, then only the primitive - * type instantiation is possible, thus sharing is not useful. - * Happens with generic math interfaces. - */ if ((!ctx->class_inst || is_primitive_inst (ctx->class_inst)) && (!ctx->method_inst || is_primitive_inst (ctx->method_inst))) { MonoGenericContainer *container = mono_class_get_generic_container (mono_class_get_generic_class (method->klass)->container_class);