From 8d5107c772b9114f6beeb51fee3c97b2ffe8cf82 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 5 Sep 2024 14:38:31 +0300 Subject: [PATCH] [mono][mini] Prefer llvmaot compiled method instead of inlining it with JIT The motivation for this is to fix crashes due to different HW intrinsics support between llvm and JIT. For example, a llvmaot compiled method might check if we have a set of HW intrinsics available and proceed with a code path that will end up calling a method that assumes intrinsics support that is not present in the aot image (because the gsharedvt version is not emitted for example). In this scenario, the called method will end up being compiled with JIT where we would crash due to missing HW intrinsics support. --- src/mono/mono/mini/aot-runtime.c | 12 ++++++++++++ src/mono/mono/mini/aot-runtime.h | 1 + src/mono/mono/mini/method-to-ir.c | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 113984590689b..d4c29ed26cdf2 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -6547,6 +6547,12 @@ mono_aot_get_method_flags (guint8 *code) return (MonoAotMethodFlags)flags; } +MonoAotFileFlags +mono_aot_get_module_flags (gpointer aot_module) +{ + return ((MonoAotModule*)aot_module)->info.flags; +} + #else /* AOT disabled */ @@ -6747,4 +6753,10 @@ mono_aot_get_method_flags (guint8 *code) return MONO_AOT_METHOD_FLAG_NONE; } +MonoAotFileFlags +mono_aot_get_module_flags (gpointer aot_module) +{ + return 0; +} + #endif diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index e4f84523c45e2..b2d30cdae2680 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -282,6 +282,7 @@ guint32 mono_aot_find_method_index (MonoMethod *method); gboolean mono_aot_init_llvm_method (gpointer aot_module, gpointer method_info, MonoClass *init_class, MonoError *error); GHashTable *mono_aot_get_weak_field_indexes (MonoImage *image); MonoAotMethodFlags mono_aot_get_method_flags (guint8 *code); +MonoAotFileFlags mono_aot_get_module_flags (gpointer aot_module); #ifdef MONO_ARCH_CODE_EXEC_ONLY typedef guint32 (*MonoAotResolvePltInfoOffset)(gpointer amodule, guint32 plt_entry_index); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 6734b2d0ce5c3..164adfcdc18cc 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -4179,6 +4179,16 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method) if (method_does_not_return (method)) return FALSE; + MonoAotModule *amodule = m_class_get_image (method->klass)->aot_module; + if (amodule && (amodule != AOT_MODULE_NOT_FOUND) && (mono_aot_get_module_flags (amodule) & MONO_AOT_FILE_FLAG_WITH_LLVM)) { + ERROR_DECL (error); + mono_class_init_internal (method->klass); + gpointer addr = mono_aot_get_method (method, error); + // If method is present in aot image compiled with llvm, we don't inline it + if (addr && is_ok (error)) + return FALSE; + } + return TRUE; }