From 95654d0997c14955a0ca8dd7613e43089da1c9b9 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 7 Oct 2022 09:30:29 -0400 Subject: [PATCH] [mono][interp] Fix an issue with deopt and interpreter tiering. If a method is tiered while being run from interp_run_clause_with_il_state (), the clause_args argument to interp_exec_method () still contains the old IL offsets confusing the EH code, i.e. this line: ``` if (clause_args && frame == clause_args->exec_frame && context->handler_ip >= clause_args->end_at_ip) ``` Clear out clause_args at the beginning to avoid this. Hopefully fixes https://github.com/dotnet/runtime/issues/76134 https://github.com/dotnet/runtime/issues/74302 --- src/mono/mono/mini/interp/interp.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 1e39fb5808383..e4afcd2f5c946 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -94,6 +94,7 @@ struct FrameClauseArgs { const guint16 *end_at_ip; /* Frame that is executing this clause */ InterpFrame *exec_frame; + gboolean run_until_end; }; /* @@ -3595,6 +3596,13 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs INIT_INTERP_STATE (frame, clause_args); + if (clause_args && clause_args->run_until_end) + /* + * Called from run_with_il_state to run the method until the end. + * Clear this out so it doesn't confuse the rest of the code. + */ + clause_args = NULL; + #ifdef ENABLE_EXPERIMENT_TIERED mini_tiered_inc (frame->imethod->method, &frame->imethod->tiered_counter, 0); #endif @@ -7660,10 +7668,13 @@ interp_run_clause_with_il_state (gpointer il_state_ptr, int clause_index, MonoOb clause_args.start_with_ip = (const guint16*)ei->data.filter; else clause_args.start_with_ip = (const guint16*)ei->handler_start; - if (clause_type == MONO_EXCEPTION_CLAUSE_NONE || clause_type == MONO_EXCEPTION_CLAUSE_FILTER) - clause_args.end_at_ip = (const guint16*)clause_args.start_with_ip + 0xffffff; - else + if (clause_type == MONO_EXCEPTION_CLAUSE_NONE || clause_type == MONO_EXCEPTION_CLAUSE_FILTER) { + /* Run until the end */ + clause_args.end_at_ip = NULL; + clause_args.run_until_end = TRUE; + } else { clause_args.end_at_ip = (const guint16*)ei->data.handler_end; + } clause_args.exec_frame = &frame; if (clause_type == MONO_EXCEPTION_CLAUSE_NONE || clause_type == MONO_EXCEPTION_CLAUSE_FILTER)