Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Precompute the CallInfo structure used by the mono_arch_..nati… #88369

Merged
merged 3 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use a CAS here to avoid leaks from races

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory is allocated from the mem manager, so its going to be leaked anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Also a mono_memory_write_barrier here is enough.

}
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