From b5bd2e7881da2d609385274bdab49d83277cd823 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Tue, 4 Feb 2020 07:02:42 -0500 Subject: [PATCH] When the interpreter does recurse, use a different function (#31635) for each call site, so you can tell from a WebAssembly stack which case it is. i.e. with function names but no line numbers. With this, we can see that call_varargs contributes to the problem here: https://github.com/mono/mono/issues/18646 Also, do not inline the interpreter, it probably/hopefully never was. Co-authored-by: Jay Krell --- src/mono/mono/mini/interp/interp.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 17b6fde..82688e2 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -290,6 +290,31 @@ static gboolean ss_enabled; static gboolean interp_init_done = FALSE; static void interp_exec_method_full (InterpFrame *frame, ThreadContext *context, FrameClauseArgs *clause_args, MonoError *error); + +static MONO_NEVER_INLINE void +interp_exec_method_call_vararg (InterpFrame *frame, ThreadContext *context, MonoError *error) +// This function makes WebAsssembly stacks clearer, so you can see which recursion +// is occuring, in the absence of line numbers in the debugger. +{ + interp_exec_method_full (frame, context, NULL, error); +} + +static MONO_NEVER_INLINE void +interp_exec_method_newobj_fast (InterpFrame *frame, ThreadContext *context, MonoError *error) +// This function makes WebAsssembly stacks clearer, so you can see which recursion +// is occuring, in the absence of line numbers in the debugger. +{ + interp_exec_method_full (frame, context, NULL, error); +} + +static MONO_NEVER_INLINE void +interp_exec_method_newobj_vtst_fast (InterpFrame *frame, ThreadContext *context, MonoError *error) +// This function makes WebAsssembly stacks clearer, so you can see which recursion +// is occuring, in the absence of line numbers in the debugger. +{ + interp_exec_method_full (frame, context, NULL, error); +} + static InterpMethod* lookup_method_pointer (gpointer addr); typedef void (*ICallMethod) (InterpFrame *frame); @@ -3485,7 +3510,7 @@ method_entry (ThreadContext *context, InterpFrame *frame, gboolean *out_tracing, * to return error information. * FRAME is only valid until the next call to alloc_frame (). */ -static void +static MONO_NEVER_INLINE void interp_exec_method_full (InterpFrame *frame, ThreadContext *context, FrameClauseArgs *clause_args, MonoError *error) { /* Interpreter main loop state (InterpState) */ @@ -3951,7 +3976,7 @@ retry_callvirt_fast: sp -= child_frame->imethod->param_count + child_frame->imethod->hasthis + num_varargs; child_frame->stack_args = sp; - interp_exec_method (child_frame, context, error); + interp_exec_method_call_vararg (child_frame, context, error); CHECK_RESUME_STATE (context); if (csig->ret->type != MONO_TYPE_VOID) { *sp = *retval; @@ -5111,7 +5136,7 @@ retry_callvirt_fast: frame->ip = ip; child_frame = alloc_frame (context, &vtable, frame, ctor_method, sp, NULL); - interp_exec_method (child_frame, context, error); + interp_exec_method_newobj_fast (child_frame, context, error); CHECK_RESUME_STATE (context); sp [0].data.o = o; sp++; @@ -5142,7 +5167,7 @@ retry_callvirt_fast: sp->data.p = vt_sp; ip += 4; - interp_exec_method (child_frame, context, error); + interp_exec_method_newobj_vtst_fast (child_frame, context, error); CHECK_RESUME_STATE (context); sp->data.p = vt_sp; -- 2.7.4