Skip to content

Commit

Permalink
[mono] Precompute the CallInfo structure used by the mono_arch_..nati… (
Browse files Browse the repository at this point in the history
#88369)

* [mono] Precompute the CallInfo structure used by the mono_arch_..native_call_context_.. functions.

* Fix indentation.

* Fix the arm build.
  • Loading branch information
vargaz authored Jul 10, 2023
1 parent 9b37c98 commit 09f4951
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 88 deletions.
19 changes: 15 additions & 4 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1680,8 +1680,15 @@ ves_pinvoke_method (
}

#ifdef MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP
gpointer call_info = *cache;

if (!call_info) {
call_info = mono_arch_get_interp_native_call_info (get_default_mem_manager (), sig);
mono_memory_barrier ();
*cache = call_info;
}
CallContext ccontext;
mono_arch_set_native_call_context_args (&ccontext, &frame, sig);
mono_arch_set_native_call_context_args (&ccontext, &frame, sig, call_info);
args = &ccontext;
#else
InterpMethodArguments *margs = build_args_from_sig (sig, &frame);
Expand All @@ -1705,7 +1712,7 @@ ves_pinvoke_method (

#ifdef MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP
if (!context->has_resume_state) {
mono_arch_get_native_call_context_ret (&ccontext, &frame, sig);
mono_arch_get_native_call_context_ret (&ccontext, &frame, sig, call_info);
}

g_free (ccontext.stack);
Expand Down Expand Up @@ -3045,8 +3052,10 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype
frame.stack = sp;
frame.retval = sp;

gpointer call_info = mono_arch_get_interp_native_call_info (NULL, sig);

/* Copy the args saved in the trampoline to the frame stack */
gpointer retp = mono_arch_get_native_call_context_args (ccontext, &frame, sig);
gpointer retp = mono_arch_get_native_call_context_args (ccontext, &frame, sig, call_info);

/* Allocate storage for value types */
stackval *newsp = sp;
Expand Down Expand Up @@ -3087,7 +3096,9 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype

/* Write back the return value */
/* 'frame' is still valid */
mono_arch_set_native_call_context_ret (ccontext, &frame, sig, retp);
mono_arch_set_native_call_context_ret (ccontext, &frame, sig, call_info, retp);

mono_arch_free_interp_native_call_info (call_info);
}

#else
Expand Down
60 changes: 41 additions & 19 deletions src/mono/mono/mini/mini-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,14 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
#endif /* !TARGET_WIN32 */
}

static int
call_info_size (MonoMethodSignature *sig)
{
int n = sig->hasthis + sig->param_count;

return sizeof (CallInfo) + (sizeof (ArgInfo) * n);
}

/*
* get_call_info:
*
Expand All @@ -859,10 +867,11 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
CallInfo *cinfo;
gboolean is_pinvoke = sig->pinvoke;

int size = call_info_size (sig);
if (mp)
cinfo = (CallInfo *)mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
cinfo = (CallInfo *)mono_mempool_alloc0 (mp, size);
else
cinfo = (CallInfo *)g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n));
cinfo = (CallInfo *)g_malloc0 (size);

cinfo->nargs = n;
cinfo->gsharedvt = mini_is_gsharedvt_variable_signature (sig);
Expand Down Expand Up @@ -1178,11 +1187,33 @@ arg_set_val (CallContext *ccontext, ArgInfo *ainfo, gpointer src)
}
}

void
mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig)
gpointer
mono_arch_get_interp_native_call_info (MonoMemoryManager *mem_manager, MonoMethodSignature *sig)
{
CallInfo *cinfo = get_call_info (NULL, sig);
if (mem_manager) {
int size = call_info_size (sig);
gpointer res = mono_mem_manager_alloc0 (mem_manager, size);
memcpy (res, cinfo, size);
g_free (cinfo);
return res;
} else {
return cinfo;
}
}

void
mono_arch_free_interp_native_call_info (gpointer call_info)
{
/* Allocated by get_call_info () */
g_free (call_info);
}

void
mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info)
{
const MonoEECallbacks *interp_cb = mini_get_interp_callbacks ();
CallInfo *cinfo = (CallInfo*)call_info;
gpointer storage;
ArgInfo *ainfo;

Expand Down Expand Up @@ -1222,23 +1253,20 @@ mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, M
if (temp_size)
arg_set_val (ccontext, ainfo, storage);
}

g_free (cinfo);
}

void
mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer retp)
mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info, gpointer retp)
{
const MonoEECallbacks *interp_cb;
CallInfo *cinfo;
CallInfo *cinfo = (CallInfo*)call_info;
gpointer storage;
ArgInfo *ainfo;

if (sig->ret->type == MONO_TYPE_VOID)
return;

interp_cb = mini_get_interp_callbacks ();
cinfo = get_call_info (NULL, sig);
ainfo = &cinfo->ret;

if (retp) {
Expand All @@ -1263,15 +1291,13 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
if (temp_size)
arg_set_val (ccontext, ainfo, storage);
}

g_free (cinfo);
}

gpointer
mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig)
mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info)
{
const MonoEECallbacks *interp_cb = mini_get_interp_callbacks ();
CallInfo *cinfo = get_call_info (NULL, sig);
CallInfo *cinfo = (CallInfo*)call_info;
gpointer storage;
ArgInfo *ainfo;

Expand Down Expand Up @@ -1302,15 +1328,14 @@ mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, M
if (ainfo->storage == ArgValuetypeAddrInIReg)
storage = (gpointer) ccontext->gregs [cinfo->ret.reg];
}
g_free (cinfo);
return storage;
}

void
mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig)
mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info)
{
const MonoEECallbacks *interp_cb;
CallInfo *cinfo;
CallInfo *cinfo = (CallInfo*)call_info;
ArgInfo *ainfo;
gpointer storage;

Expand All @@ -1319,7 +1344,6 @@ mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
return;

interp_cb = mini_get_interp_callbacks ();
cinfo = get_call_info (NULL, sig);
ainfo = &cinfo->ret;

/* The return values were stored directly at address passed in reg */
Expand All @@ -1334,8 +1358,6 @@ mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
}
interp_cb->data_to_frame_arg ((MonoInterpFrameHandle)frame, sig, -1, storage);
}

g_free (cinfo);
}

/*
Expand Down
58 changes: 40 additions & 18 deletions src/mono/mono/mini/mini-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,14 @@ is_hfa (MonoType *t, int *out_nfields, int *out_esize)
return TRUE;
}

static int
call_info_size (MonoMethodSignature *sig)
{
int n = sig->hasthis + sig->param_count;

return sizeof (CallInfo) + (sizeof (ArgInfo) * n);
}

static CallInfo*
get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
{
Expand All @@ -1268,9 +1276,9 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
gboolean vtype_retaddr = FALSE;

if (mp)
cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
cinfo = mono_mempool_alloc0 (mp, call_info_size (sig));
else
cinfo = g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n));
cinfo = g_malloc0 (call_info_size (sig));

cinfo->nargs = n;
gr = ARMREG_R0;
Expand Down Expand Up @@ -1666,12 +1674,34 @@ arg_set_val (CallContext *ccontext, ArgInfo *ainfo, gpointer src)
memcpy (ccontext->stack + ainfo->offset, (host_mgreg_t*)src + ainfo->size, ainfo->struct_size - reg_size);
}

gpointer
mono_arch_get_interp_native_call_info (MonoMemoryManager *mem_manager, MonoMethodSignature *sig)
{
CallInfo *cinfo = get_call_info (NULL, sig);
if (mem_manager) {
int size = call_info_size (sig);
gpointer res = mono_mem_manager_alloc0 (mem_manager, size);
memcpy (res, cinfo, size);
g_free (cinfo);
return res;
} else {
return cinfo;
}
}

void
mono_arch_free_interp_native_call_info (gpointer call_info)
{
/* Allocated by get_call_info () */
g_free (call_info);
}

/* Set arguments in the ccontext (for i2n entry) */
void
mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig)
mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info)
{
const MonoEECallbacks *interp_cb = mini_get_interp_callbacks ();
CallInfo *cinfo = get_call_info (NULL, sig);
CallInfo *cinfo = (CallInfo*)call_info;
gpointer storage;
ArgInfo *ainfo;

Expand Down Expand Up @@ -1704,24 +1734,21 @@ mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, M
if (temp_size)
arg_set_val (ccontext, ainfo, storage);
}

g_free (cinfo);
}

/* Set return value in the ccontext (for n2i return) */
void
mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer retp)
mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info, gpointer retp)
{
const MonoEECallbacks *interp_cb;
CallInfo *cinfo;
CallInfo *cinfo = (CallInfo*)call_info;
gpointer storage;
ArgInfo *ainfo;

if (sig->ret->type == MONO_TYPE_VOID)
return;

interp_cb = mini_get_interp_callbacks ();
cinfo = get_call_info (NULL, sig);
ainfo = &cinfo->ret;

if (retp) {
Expand All @@ -1734,16 +1761,14 @@ mono_arch_set_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
memset (ccontext, 0, sizeof (CallContext)); // FIXME
interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, -1, storage);
}

g_free (cinfo);
}

/* Gets the arguments from ccontext (for n2i entry) */
gpointer
mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig)
mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info)
{
const MonoEECallbacks *interp_cb = mini_get_interp_callbacks ();
CallInfo *cinfo = get_call_info (NULL, sig);
CallInfo *cinfo = (CallInfo*)call_info;
gpointer storage;
ArgInfo *ainfo;

Expand All @@ -1767,16 +1792,15 @@ mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, M
storage = (gpointer)(gsize)ccontext->gregs [cinfo->ret.reg];
}

g_free (cinfo);
return storage;
}

/* Gets the return value from ccontext (for i2n exit) */
void
mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig)
mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig, gpointer call_info)
{
const MonoEECallbacks *interp_cb;
CallInfo *cinfo;
CallInfo *cinfo = (CallInfo*)call_info;
ArgInfo *ainfo;
gpointer storage;

Expand All @@ -1792,8 +1816,6 @@ mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, Mo
storage = arg_get_storage (ccontext, ainfo);
interp_cb->data_to_frame_arg ((MonoInterpFrameHandle)frame, sig, -1, storage);
}

g_free (cinfo);
}

#ifndef DISABLE_JIT
Expand Down
Loading

0 comments on commit 09f4951

Please sign in to comment.