Skip to content

Commit

Permalink
[mono] Disable partial generic sharing for gparams with non-enum cons…
Browse files Browse the repository at this point in the history
…traints 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 dotnet#60447.
  • Loading branch information
vargaz committed Jan 14, 2022
1 parent 27fdc2d commit 77ee77c
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions src/mono/mono/mini/mini-generic-sharing.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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);
Expand Down

0 comments on commit 77ee77c

Please sign in to comment.