From 498731be929ca70b0cb363bccd9a890f50a1bec4 Mon Sep 17 00:00:00 2001 From: vargaz Date: Tue, 24 Mar 2020 18:29:45 +0000 Subject: [PATCH] [llvmonly] Throw an ExecutionEngine exception with a helpful message when we try to execute a method which failed AOT compilation. --- src/mono/mono/metadata/jit-icall-reg.h | 2 +- src/mono/mono/mini/llvmonly-runtime.c | 13 +++++-------- src/mono/mono/mini/llvmonly-runtime.h | 2 +- src/mono/mono/mini/mini-llvm.c | 18 +++++++++++++++--- src/mono/mono/mini/mini-runtime.c | 2 +- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 92670dd8af79ac..125c0b5a8ae923 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -139,7 +139,7 @@ MONO_JIT_ICALL (mini_llvmonly_resolve_generic_virtual_iface_call) \ MONO_JIT_ICALL (mini_llvmonly_resolve_iface_call_gsharedvt) \ MONO_JIT_ICALL (mini_llvmonly_resolve_vcall_gsharedvt) \ MONO_JIT_ICALL (mini_llvmonly_throw_nullref_exception) \ -MONO_JIT_ICALL (mini_llvmonly_throw_missing_method_exception) \ +MONO_JIT_ICALL (mini_llvmonly_throw_aot_failed_exception) \ MONO_JIT_ICALL (mono_amd64_resume_unwind) \ MONO_JIT_ICALL (mono_amd64_start_gsharedvt_call) \ MONO_JIT_ICALL (mono_amd64_throw_corlib_exception) \ diff --git a/src/mono/mono/mini/llvmonly-runtime.c b/src/mono/mono/mini/llvmonly-runtime.c index 63fc11de3ede99..3104e2975783c8 100644 --- a/src/mono/mono/mini/llvmonly-runtime.c +++ b/src/mono/mono/mini/llvmonly-runtime.c @@ -809,14 +809,11 @@ mini_llvmonly_throw_nullref_exception (void) mono_llvm_throw_corlib_exception (ex_token_index); } -static GENERATE_GET_CLASS_WITH_CACHE (missing_method, "System", "MissingMethodException") - void -mini_llvmonly_throw_missing_method_exception (void) +mini_llvmonly_throw_aot_failed_exception (const char *name) { - MonoClass *klass = mono_class_get_missing_method_class (); - - guint32 ex_token_index = m_class_get_type_token (klass) - MONO_TOKEN_TYPE_DEF; - - mono_llvm_throw_corlib_exception (ex_token_index); + char *msg = g_strdup_printf ("AOT Compilation failed for method '%s'.", name); + MonoException *ex = mono_get_exception_execution_engine (msg); + g_free (msg); + mono_llvm_throw_exception ((MonoObject*)ex); } diff --git a/src/mono/mono/mini/llvmonly-runtime.h b/src/mono/mono/mini/llvmonly-runtime.h index eadc4c28906c97..f939916a0dc058 100644 --- a/src/mono/mono/mini/llvmonly-runtime.h +++ b/src/mono/mono/mini/llvmonly-runtime.h @@ -33,6 +33,6 @@ G_EXTERN_C void mini_llvm_init_method (MonoAotFileInfo *info, gpointer G_EXTERN_C void mini_llvmonly_throw_nullref_exception (void); -G_EXTERN_C void mini_llvmonly_throw_missing_method_exception (void); +G_EXTERN_C void mini_llvmonly_throw_aot_failed_exception (const char *name); #endif diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 77a7c1c38ee695..d2462d37d12565 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -9542,10 +9542,22 @@ emit_method_inner (EmitContext *ctx) ctx->builder = create_builder (ctx); LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb); + char *name = mono_method_get_full_name (cfg->method); + int len = strlen (name); + + LLVMTypeRef type = LLVMArrayType (LLVMInt8Type (), len + 1); + LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, type, "missing_method_name"); + LLVMSetVisibility (name_var, LLVMHiddenVisibility); + LLVMSetLinkage (name_var, LLVMInternalLinkage); + LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((guint8*)name, len + 1)); + mono_llvm_set_is_constant (name_var); + g_free (name); + if (!sig) - sig = LLVMFunctionType0 (LLVMVoidType (), FALSE); - LLVMValueRef callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_throw_missing_method_exception)); - LLVMBuildCall (ctx->builder, callee, NULL, 0, ""); + sig = LLVMFunctionType1 (LLVMVoidType (), ctx->module->ptr_type, FALSE); + LLVMValueRef callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_throw_aot_failed_exception)); + LLVMValueRef args [] = { convert (ctx, name_var, ctx->module->ptr_type) }; + LLVMBuildCall (ctx->builder, callee, args, 1, ""); LLVMBuildUnreachable (ctx->builder); } diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 30610c29b9ec83..b5cf9e4643dfa2 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4672,7 +4672,7 @@ register_icalls (void) register_icall (mini_llvmonly_init_delegate, mono_icall_sig_void_object, TRUE); register_icall (mini_llvmonly_init_delegate_virtual, mono_icall_sig_void_object_object_ptr, TRUE); register_icall (mini_llvmonly_throw_nullref_exception, mono_icall_sig_void, TRUE); - register_icall (mini_llvmonly_throw_missing_method_exception, mono_icall_sig_void, TRUE); + register_icall (mini_llvmonly_throw_aot_failed_exception, mono_icall_sig_void_ptr, TRUE); register_icall (mono_get_assembly_object, mono_icall_sig_object_ptr, TRUE); register_icall (mono_get_method_object, mono_icall_sig_object_ptr, TRUE);