Skip to content

Commit

Permalink
[Mono] added arm64 SwiftError support to interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
jkurdek committed May 14, 2024
1 parent bad00cf commit a135604
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/mono/mono/mini/interp/interp-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
27 changes: 26 additions & 1 deletion src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
16 changes: 15 additions & 1 deletion src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand All @@ -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);
}
Expand Down
13 changes: 13 additions & 0 deletions src/mono/mono/mini/tramp-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2145,9 +2145,6 @@
<ExcludeList Include = "$(XUnitTestBinBase)/JIT/Directed/Arrays/nintindexoutofrange/**">
<Issue>https://github.com/dotnet/runtime/issues/71656</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Interop/Swift/SwiftErrorHandling/**">
<Issue>Reverse P/Invokes not supported yet</Issue>
</ExcludeList>
<!-- End interpreter issues -->
</ItemGroup>

Expand Down

0 comments on commit a135604

Please sign in to comment.