From c580f49f6527ac8df28876c4156345bc0a73ba64 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 12 Nov 2021 17:11:29 -0500 Subject: [PATCH] [mono][jit] Optimize calls to Type:get_IsValueType () on gshared constrained types. (#61514) These are used for example in Span:.ctor (). --- src/mono/mono/mini/intrinsics.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index 4e89ab2d0f1a4..92ac9ef74564a 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -1894,6 +1894,33 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MONO_ADD_INS (cfg->cbb, ins); } return ins; + } else if (cmethod->klass == mono_defaults.systemtype_class && !strcmp (cmethod->name, "get_IsValueType") && + args [0]->klass == mono_defaults.runtimetype_class) { + MonoClass *k1 = get_class_from_ldtoken_ins (args [0]); + if (k1) { + MonoType *t1 = m_class_get_byval_arg (k1); + MonoType *constraint1 = NULL; + + /* Common case in gshared BCL code: t1 is a gshared type like T_INT */ + if (mono_class_is_gparam (k1)) { + MonoGenericParam *gparam = t1->data.generic_param; + constraint1 = gparam->gshared_constraint; + if (constraint1) { + if (constraint1->type == MONO_TYPE_OBJECT) { + if (cfg->verbose_level > 2) + printf ("-> false\n"); + EMIT_NEW_ICONST (cfg, ins, 0); + return ins; + } else if (MONO_TYPE_IS_PRIMITIVE (constraint1)) { + if (cfg->verbose_level > 2) + printf ("-> true\n"); + EMIT_NEW_ICONST (cfg, ins, 1); + return ins; + } + } + } + } + return NULL; } else if (((!strcmp (cmethod_klass_image->assembly->aname.name, "MonoMac") || !strcmp (cmethod_klass_image->assembly->aname.name, "monotouch")) && !strcmp (cmethod_klass_name_space, "XamCore.ObjCRuntime") &&