From a1356042e3712efff393182bb0c00aeb27819fde Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Tue, 14 May 2024 11:35:15 +0200 Subject: [PATCH] [Mono] added arm64 SwiftError support to interpreter --- src/mono/mono/mini/interp/interp-internals.h | 1 + src/mono/mono/mini/interp/interp.c | 27 +++++++++++++- src/mono/mono/mini/interp/transform.c | 37 ++++++++++++++++++++ src/mono/mono/mini/mini-arm64.c | 16 ++++++++- src/mono/mono/mini/tramp-arm64.c | 13 +++++++ src/tests/issues.targets | 3 -- 6 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/interp/interp-internals.h b/src/mono/mono/mini/interp/interp-internals.h index 43534b51e07fba..5fe04bf314c8c7 100644 --- a/src/mono/mono/mini/interp/interp-internals.h +++ b/src/mono/mono/mini/interp/interp-internals.h @@ -155,6 +155,7 @@ struct InterpMethod { MonoProfilerCallInstrumentationFlags prof_flags; InterpMethodCodeType code_type; int ref_slot_offset; // GC visible pointer slot + int swift_error_offset; // swift error struct MonoBitSet *ref_slots; #ifdef ENABLE_EXPERIMENT_TIERED MiniTieredCounter tiered_counter; diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 3e25c7acc29665..536e9c345e8469 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -3176,6 +3176,20 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype /* Copy the args saved in the trampoline to the frame stack */ gpointer retp = mono_arch_get_native_call_context_args (ccontext, &frame, sig, call_info); +#ifdef MONO_ARCH_HAVE_SWIFTCALL + int swift_error_arg_index = -1; + gpointer swift_error_data; + gpointer* swift_error_pointer; + if (mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL)) { + swift_error_data = mono_arch_get_swift_error (ccontext, sig, &swift_error_arg_index); + + int swift_error_offset = frame.imethod->swift_error_offset; + if (swift_error_offset >= 0) { + swift_error_pointer = (gpointer*)((guchar*)frame.stack + swift_error_offset); + } + } +#endif + /* Allocate storage for value types */ stackval *newsp = sp; /* FIXME we should reuse computation on imethod for this */ @@ -3195,6 +3209,11 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype } else { size = MINT_STACK_SLOT_SIZE; } +#ifdef MONO_ARCH_HAVE_SWIFTCALL + if (swift_error_arg_index >= 0 && swift_error_arg_index == i) { + newsp->data.p = swift_error_pointer; + } +#endif newsp = STACK_ADD_BYTES (newsp, size); } newsp = (stackval*)ALIGN_TO (newsp, MINT_STACK_ALIGNMENT); @@ -3205,6 +3224,12 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype mono_interp_exec_method (&frame, context, NULL); MONO_EXIT_GC_UNSAFE; +#ifdef MONO_ARCH_HAVE_SWIFTCALL + if (swift_error_arg_index >= 0) { + *(gpointer*)swift_error_data = *(gpointer*)swift_error_pointer; + } +#endif + context->stack_pointer = (guchar*)sp; g_assert (!context->has_resume_state); @@ -3459,7 +3484,7 @@ interp_create_method_pointer (MonoMethod *method, gboolean compile, MonoError *e return (gpointer)no_llvmonly_interp_method_pointer; } -#ifndef MONO_ARCH_HAVE_FTNPTR_ARG_TRAMPOLINE +#if !defined(MONO_ARCH_HAVE_FTNPTR_ARG_TRAMPOLINE) && !defined(MONO_ARCH_HAVE_SWIFTCALL) /* * Interp in wrappers get the argument in the rgctx register. If * MONO_ARCH_HAVE_FTNPTR_ARG_TRAMPOLINE is defined it means that diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index d540cec6a9780f..ef5eabe7e48a98 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -4417,6 +4417,43 @@ interp_method_compute_offsets (TransformData *td, InterpMethod *imethod, MonoMet td->il_locals_size = offset - td->il_locals_offset; td->total_locals_size = offset; +#ifdef MONO_ARCH_HAVE_SWIFTCALL + // Allocate SwiftError + if (mono_method_signature_has_ext_callconv (sig, MONO_EXT_CALLCONV_SWIFTCALL)) { + imethod->swift_error_offset = -1; + + MonoClass *swift_error = mono_class_try_get_swift_error_class (); + MonoClass *swift_error_ptr = mono_class_create_ptr (m_class_get_this_arg (swift_error)); + + int swift_error_index = -1; + for (int i = 0; i < sig->param_count; i++) { + MonoClass *klass = mono_class_from_mono_type_internal (sig->params [i]); + if (klass == swift_error_ptr) { + swift_error_index = i; + break; + } + } + + if (swift_error_index >= 0) + { + MonoType* type = mono_method_signature_internal (td->method)->params [swift_error_index - sig->hasthis]; + int index = num_args + num_il_locals; + int mt = mono_mint_type (type); + + td->vars [index].type = type; + td->vars [index].global = TRUE; + td->vars [index].offset = offset; + size = mono_interp_type_size (type, mt, &align); + td->vars [index].size = size; + interp_mark_ref_slots_for_var (td, index); + + offset += size; + offset = ALIGN_TO (offset, MINT_STACK_ALIGNMENT); + imethod->swift_error_offset = td->vars [index].offset; + } + } +#endif + imethod->clause_data_offsets = (guint32*)g_malloc (header->num_clauses * sizeof (guint32)); td->clause_vars = (int*)mono_mempool_alloc (td->mempool, sizeof (int) * header->num_clauses); for (guint i = 0; i < header->num_clauses; i++) { diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 0af0da4b8030ca..0a2f66f662ecc0 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -2081,10 +2081,24 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo storage = alloca (temp_size); else storage = arg_get_storage (ccontext, ainfo); + +#ifdef MONO_ARCH_HAVE_SWIFTCALL + int swift_error_preserved_val = 0; + if (ccontext->gregs [PARAM_REGS + 2]) { + swift_error_preserved_val = ccontext->gregs [PARAM_REGS + 2]; + } +#endif + memset (ccontext, 0, sizeof (CallContext)); // FIXME interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, -1, storage); if (temp_size) arg_set_val (ccontext, ainfo, storage); + +#ifdef MONO_ARCH_HAVE_SWIFTCALL + if (swift_error_preserved_val > 0) { + ccontext->gregs [PARAM_REGS + 2] = swift_error_preserved_val; + } +#endif } } @@ -2105,7 +2119,7 @@ mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, M storage = alloca (temp_size); // FIXME? alloca in a loop arg_get_val (ccontext, ainfo, storage); } else { - storage = arg_get_storage (ccontext, ainfo); + storage = arg_get_storage (ccontext, ainfo); // JEREMI } interp_cb->data_to_frame_arg ((MonoInterpFrameHandle)frame, sig, i, storage); } diff --git a/src/mono/mono/mini/tramp-arm64.c b/src/mono/mono/mini/tramp-arm64.c index 7e8483409610cd..ac34bde82c693b 100644 --- a/src/mono/mono/mini/tramp-arm64.c +++ b/src/mono/mono/mini/tramp-arm64.c @@ -846,6 +846,13 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info) for (i = 0; i < FP_PARAM_REGS; i++) arm_strfpx (code, i, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double)); +#ifdef MONO_ARCH_HAVE_SWIFTCALL + /* set context registers to CallContext */ + for (i = 0; i < CTX_REGS; i++) { + arm_strx (code, i + CTX_REGS_OFFSET, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + PARAM_REGS + 1) * sizeof (host_mgreg_t)); + } +#endif + /* set the stack pointer to the value at call site */ arm_addx_imm (code, ARMREG_R0, ARMREG_FP, framesize); arm_strp (code, ARMREG_R0, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, stack)); @@ -863,6 +870,12 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info) for (i = 0; i < FP_PARAM_REGS; i++) arm_ldrfpx (code, i, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, fregs) + i * sizeof (double)); +#ifdef MONO_ARCH_HAVE_SWIFTCALL + /* set the context registers from CallContext */ + for (i = 0; i < CTX_REGS; i++) { + arm_ldrx (code, i + CTX_REGS_OFFSET, ARMREG_FP, ccontext_offset + MONO_STRUCT_OFFSET (CallContext, gregs) + (i + PARAM_REGS + 1) * sizeof (host_mgreg_t)); + } +#endif /* reset stack and return */ arm_ldpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0); arm_addx_imm (code, ARMREG_SP, ARMREG_SP, framesize); diff --git a/src/tests/issues.targets b/src/tests/issues.targets index a27fbb6ac4ef8b..a8b94f6576cf22 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2145,9 +2145,6 @@ https://github.com/dotnet/runtime/issues/71656 - - Reverse P/Invokes not supported yet -