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. (#63813)

This is an optimization, but it also avoids hitting some gsharing limitations wrt
calling abstract static methods from gshared code.

Fixes #60447.
  • Loading branch information
vargaz authored Jan 16, 2022
1 parent c5c7967 commit 23de817
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 23de817

Please sign in to comment.