From f37ad07cbce5eafe4e7326a3d1e49479f25544c7 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Wed, 6 Mar 2024 15:37:45 -0500 Subject: [PATCH 1/2] [mono][jit] Emit instances when using unmanaged generic calli in gshared methods. --- src/mono/mono/metadata/marshal.c | 4 ++-- src/mono/mono/mini/aot-compiler.c | 34 +++++++++++++++---------------- src/mono/mono/mini/method-to-ir.c | 4 +++- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 1b7d0b4310a2b..e9cebef7a8182 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3922,14 +3922,14 @@ mono_marshal_get_native_func_wrapper_indirect (MonoClass *caller_class, MonoMeth caller_class = mono_class_get_generic_type_definition (caller_class); MonoImage *image = m_class_get_image (caller_class); g_assert (sig->pinvoke); - g_assert (!sig->hasthis && ! sig->explicit_this); + g_assert (!sig->hasthis && !sig->explicit_this); g_assert (!sig->has_type_parameters); #if 0 /* * Since calli sigs are already part of ECMA-335, they were already used by C++/CLI, which * allowed non-blittable types. So the C# function pointers spec doesn't restrict this to - * blittable tyhpes only. + * blittable types only. */ g_assertf (type_is_blittable (sig->ret), "sig return type %s is not blittable\n", mono_type_full_name (sig->ret)); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 59791291da8c3..7778557fb7786 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -9541,6 +9541,23 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) cfg = mini_method_compile (method, acfg->jit_opts, flags, 0, index); mono_time_track_end (&mono_jit_stats.jit_time, jit_time_start); + if (cfg->prefer_instances) { + /* + * Compile the original specific instances in addition to the gshared method + * for performance reasons, since gshared methods cannot implement some + * features like static virtual methods efficiently. + */ + /* Instances encountered later will be handled in add_extra_method_full () */ + g_hash_table_insert (acfg->prefer_instances, method, method); + GPtrArray *instances = g_hash_table_lookup (acfg->gshared_instances, method); + if (instances) { + for (guint i = 0; i < instances->len; ++i) { + MonoMethod *instance = (MonoMethod*)g_ptr_array_index (instances, i); + add_extra_method_full (acfg, instance, FALSE, 0); + } + } + } + if (cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) { if (acfg->aot_opts.print_skipped_methods) printf ("Skip (gshared failure): %s (%s)\n", mono_method_get_full_name (method), cfg->exception_message); @@ -9626,23 +9643,6 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) printf ("%s ### %d\n", mono_method_get_full_name (method), cfg->code_size); } - if (cfg->prefer_instances) { - /* - * Compile the original specific instances in addition to the gshared method - * for performance reasons, since gshared methods cannot implement some - * features like static virtual methods efficiently. - */ - /* Instances encountered later will be handled in add_extra_method_full () */ - g_hash_table_insert (acfg->prefer_instances, method, method); - GPtrArray *instances = g_hash_table_lookup (acfg->gshared_instances, method); - if (instances) { - for (guint i = 0; i < instances->len; ++i) { - MonoMethod *instance = (MonoMethod*)g_ptr_array_index (instances, i); - add_extra_method_full (acfg, instance, FALSE, 0); - } - } - } - /* Adds generic instances referenced by this method */ /* * The depth is used to avoid infinite loops when generic virtual recursion is diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 324b4ba778c02..76f94e0bd0137 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -7548,8 +7548,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (cfg->compile_aot) cfg->pinvoke_calli_signatures = g_slist_prepend_mempool (cfg->mempool, cfg->pinvoke_calli_signatures, fsig); - if (fsig->has_type_parameters) + if (fsig->has_type_parameters) { + cfg->prefer_instances = TRUE; GENERIC_SHARING_FAILURE (CEE_CALLI); + } /* Call the wrapper that will do the GC transition instead */ MonoMethod *wrapper = mono_marshal_get_native_func_wrapper_indirect (method->klass, fsig, cfg->compile_aot); From 41246ec6e511616158629f2920e8ef6ee0e161f0 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Wed, 6 Mar 2024 16:14:11 -0500 Subject: [PATCH 2/2] Reenable some tests. --- src/tests/Interop/Interop.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tests/Interop/Interop.csproj b/src/tests/Interop/Interop.csproj index 0e25aba816182..6fc22f7bf4f27 100644 --- a/src/tests/Interop/Interop.csproj +++ b/src/tests/Interop/Interop.csproj @@ -21,8 +21,6 @@ - -