Skip to content

Commit

Permalink
[arm64] Remove the limitation on the number of nullable arguments for…
Browse files Browse the repository at this point in the history
… dyncalls.

Fixes xamarin/xamarin-macios#4984.
  • Loading branch information
vargaz committed Oct 16, 2018
1 parent 0beb087 commit e4efd5f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
36 changes: 31 additions & 5 deletions mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ typedef struct {
CallInfo *cinfo;
MonoType *rtype;
MonoType **param_types;
int n_fpargs, n_fpret;
int n_fpargs, n_fpret, nullable_area;
} ArchDynCallInfo;

static gboolean
Expand Down Expand Up @@ -1634,7 +1634,7 @@ mono_arch_dyn_call_prepare (MonoMethodSignature *sig)
{
ArchDynCallInfo *info;
CallInfo *cinfo;
int i;
int i, aindex;

cinfo = get_call_info (NULL, sig);

Expand Down Expand Up @@ -1663,6 +1663,28 @@ mono_arch_dyn_call_prepare (MonoMethodSignature *sig)
default:
break;
}

for (aindex = 0; aindex < sig->param_count; aindex++) {
MonoType *t = info->param_types [aindex];

if (t->byref)
continue;

switch (t->type) {
case MONO_TYPE_GENERICINST:
if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type_internal (t))) {
MonoClass *klass = mono_class_from_mono_type_internal (t);
int size;

/* Nullables need a temporary buffer, its stored at the end of DynCallArgs.regs after the stack args */
size = mono_class_value_size (klass, NULL);
info->nullable_area += size;
}
break;
default:
break;
}
}

return (MonoDynCallInfo*)info;
}
Expand All @@ -1683,7 +1705,7 @@ mono_arch_dyn_call_get_buf_size (MonoDynCallInfo *info)
ArchDynCallInfo *ainfo = (ArchDynCallInfo*)info;

g_assert (ainfo->cinfo->stack_usage % MONO_ARCH_FRAME_ALIGNMENT == 0);
return sizeof (DynCallArgs) + ainfo->cinfo->stack_usage;
return sizeof (DynCallArgs) + ainfo->cinfo->stack_usage + ainfo->nullable_area;
}

static double
Expand Down Expand Up @@ -1711,6 +1733,7 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
MonoMethodSignature *sig = dinfo->sig;
CallInfo *cinfo = dinfo->cinfo;
int buffer_offset = 0;
guint8 *nullable_buffer;

p->res = 0;
p->ret = ret;
Expand All @@ -1722,6 +1745,9 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
greg = 0;
pindex = 0;

/* Stored after the stack arguments */
nullable_buffer = (guint8*)&(p->regs [PARAM_REGS + 1 + (cinfo->stack_usage / sizeof (mgreg_t))]);

if (sig->hasthis)
p->regs [greg ++] = (mgreg_t)*(args [arg_index ++]);

Expand Down Expand Up @@ -1827,9 +1853,9 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g
* if the nullable param is passed by ref.
*/
size = mono_class_value_size (klass, NULL);
nullable_buf = p->buffer + buffer_offset;
nullable_buf = nullable_buffer + buffer_offset;
buffer_offset += size;
g_assert (buffer_offset <= 256);
g_assert (buffer_offset <= dinfo->nullable_area);

/* The argument pointed to by arg is either a boxed vtype or null */
mono_nullable_init (nullable_buf, (MonoObject*)arg, klass);
Expand Down
1 change: 0 additions & 1 deletion mono/mini/mini-arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ typedef struct {
guint8 *ret;
double fpregs [FP_PARAM_REGS];
int n_fpargs, n_fpret, n_stackargs;
guint8 buffer [256];
/* This should come last as the structure is dynamically extended */
/* The +1 is for r8 */
mgreg_t regs [PARAM_REGS + 1];
Expand Down

0 comments on commit e4efd5f

Please sign in to comment.