Fixes https://github.com/mono/mono/issues/19801.
<!--
Thank you for your Pull Request!
If you are new to contributing to Mono, please try to do your best at conforming to our coding guidelines http://www.mono-project.com/community/contributing/coding-guidelines/ but don't worry if you get something wrong. One of the project members will help you to get things landed.
Does your pull request fix any of the existing issues? Please use the following format: Fixes #issue-number
-->
Co-authored-by: vargaz <vargaz@users.noreply.github.com>
#include "mini-gc.h"
#include "mini-llvm.h"
#include "mini-runtime.h"
+#include "interp/interp.h"
static MonoMethod*
try_get_method_nofail (MonoClass *klass, const char *method_name, int param_count, int flags)
if (gsharedvt_out && g_hash_table_lookup (acfg->gsharedvt_out_signatures, sig))
add_out = FALSE;
- if (!add_in && !add_out)
+ if (!add_in && !add_out && !interp_in)
return;
if (mini_is_gsharedvt_variable_signature (sig))
if (interp_in) {
wrapper = mini_get_interp_in_wrapper (sig);
add_extra_method (acfg, wrapper);
- //printf ("X: %s\n", mono_method_full_name (wrapper, 1));
}
#endif
}
for (l = cfg->interp_in_signatures; l; l = l->next) {
MonoMethodSignature *sig = mono_metadata_signature_dup ((MonoMethodSignature*)l->data);
- add_gsharedvt_wrappers (acfg, sig, TRUE, FALSE, FALSE);
+ /*
+ * Interpreter methods in llvmonly+interp mode are called using gsharedvt_in wrappers,
+ * since we already generate those in llvmonly mode. But methods with a large
+ * number of arguments need special processing (see interp_create_method_pointer_llvmonly),
+ * which only interp_in wrappers do.
+ */
+ if (sig->param_count > MAX_INTERP_ENTRY_ARGS)
+ add_gsharedvt_wrappers (acfg, sig, FALSE, FALSE, TRUE);
+ else
+ add_gsharedvt_wrappers (acfg, sig, TRUE, FALSE, FALSE);
}
} else if (mono_aot_mode_is_full (&acfg->aot_opts) && mono_aot_mode_is_interp (&acfg->aot_opts)) {
/* The interpreter uses these wrappers to call aot-ed code */
* this/static * ret/void * 16 arguments -> 64 functions.
*/
-#define MAX_INTERP_ENTRY_ARGS 8
-
#define INTERP_ENTRY_BASE(_method, _this_arg, _res) \
InterpEntryData data; \
(data).rmethod = (_method); \
* to use a ftndesc. The caller uses a normal signature, while the
* entry functions use a gsharedvt_in signature, so wrap the entry function in
* a gsharedvt_in_sig wrapper.
+ * We use a gsharedvt_in_sig wrapper instead of an interp_in wrapper, because they
+ * are mostly the same, and they are already generated. The exception is the
+ * wrappers for methods with more than 8 arguments, those are different.
*/
- wrapper = mini_get_gsharedvt_in_sig_wrapper (sig);
+ if (sig->param_count > MAX_INTERP_ENTRY_ARGS)
+ wrapper = mini_get_interp_in_wrapper (sig);
+ else
+ wrapper = mini_get_gsharedvt_in_sig_wrapper (sig);
entry_wrapper = mono_jit_compile_method_jit_only (wrapper, error);
mono_error_assertf_ok (error, "couldn't compile wrapper \"%s\" for \"%s\"",
mono_method_get_name_full (method, TRUE, TRUE, MONO_TYPE_NAME_FORMAT_IL));
if (sig->param_count > MAX_INTERP_ENTRY_ARGS) {
- g_assert_not_reached ();
- //entry_func = (gpointer)interp_entry_general;
+ entry_func = (gpointer)interp_entry_general;
} else if (sig->hasthis) {
if (sig->ret->type == MONO_TYPE_VOID)
entry_func = entry_funcs_instance [sig->param_count];
#define INTERP_ICALL_TRAMP_FARGS 4
#endif
+#define MAX_INTERP_ENTRY_ARGS 8
+
struct _InterpMethodArguments {
size_t ilen;
gpointer *iargs;
#include "aot-runtime.h"
#include "mini-runtime.h"
#include "llvmonly-runtime.h"
+#include "interp/interp.h"
#define ALLOW_PARTIAL_SHARING TRUE
//#define ALLOW_PARTIAL_SHARING FALSE
return res;
}
- if (sig->param_count > 8)
+ if (sig->param_count > MAX_INTERP_ENTRY_ARGS)
/* Call the generic interpreter entry point, the specialized ones only handle a limited number of arguments */
generic = TRUE;