From e4efd5f298eb9340acf9b12cab822b2c99c7eff2 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 16 Oct 2018 03:04:31 +0200 Subject: [PATCH] [arm64] Remove the limitation on the number of nullable arguments for dyncalls. Fixes https://github.com/xamarin/xamarin-macios/issues/4984. --- mono/mini/mini-arm64.c | 36 +++++++++++++++++++++++++++++++----- mono/mini/mini-arm64.h | 1 - 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/mono/mini/mini-arm64.c b/mono/mini/mini-arm64.c index bf444b054625..83cd5e60da61 100644 --- a/mono/mini/mini-arm64.c +++ b/mono/mini/mini-arm64.c @@ -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 @@ -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); @@ -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; } @@ -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 @@ -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; @@ -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 ++]); @@ -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); diff --git a/mono/mini/mini-arm64.h b/mono/mini/mini-arm64.h index ca09c157c43d..bc31f4432e0c 100644 --- a/mono/mini/mini-arm64.h +++ b/mono/mini/mini-arm64.h @@ -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];