Skip to content

Commit d933222

Browse files
[release/7.0] [mono][interp] Fix an issue with deopt and interpreter tiering. (#77059)
* [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 #76134 #74302 * [mono][interp] Avoid tiering up methods while running clauses. The IL offsets in the clause_args argument become out-of-date after tiering up. Co-authored-by: Zoltan Varga <[email protected]>
1 parent 00816bf commit d933222

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/mono/mono/mini/interp/interp.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct FrameClauseArgs {
9494
const guint16 *end_at_ip;
9595
/* Frame that is executing this clause */
9696
InterpFrame *exec_frame;
97+
gboolean run_until_end;
9798
};
9899

99100
/*
@@ -3595,6 +3596,13 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
35953596

35963597
INIT_INTERP_STATE (frame, clause_args);
35973598

3599+
if (clause_args && clause_args->run_until_end)
3600+
/*
3601+
* Called from run_with_il_state to run the method until the end.
3602+
* Clear this out so it doesn't confuse the rest of the code.
3603+
*/
3604+
clause_args = NULL;
3605+
35983606
#ifdef ENABLE_EXPERIMENT_TIERED
35993607
mini_tiered_inc (frame->imethod->method, &frame->imethod->tiered_counter, 0);
36003608
#endif
@@ -7067,15 +7075,15 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
70677075

70687076
MINT_IN_CASE(MINT_TIER_ENTER_METHOD) {
70697077
frame->imethod->entry_count++;
7070-
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT)
7078+
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT && !clause_args)
70717079
ip = mono_interp_tier_up_frame_enter (frame, context);
70727080
else
70737081
ip++;
70747082
MINT_IN_BREAK;
70757083
}
70767084
MINT_IN_CASE(MINT_TIER_PATCHPOINT) {
70777085
frame->imethod->entry_count++;
7078-
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT)
7086+
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT && !clause_args)
70797087
ip = mono_interp_tier_up_frame_patchpoint (frame, context, ip [1]);
70807088
else
70817089
ip += 2;
@@ -7656,10 +7664,13 @@ interp_run_clause_with_il_state (gpointer il_state_ptr, int clause_index, MonoOb
76567664
clause_args.start_with_ip = (const guint16*)ei->data.filter;
76577665
else
76587666
clause_args.start_with_ip = (const guint16*)ei->handler_start;
7659-
if (clause_type == MONO_EXCEPTION_CLAUSE_NONE || clause_type == MONO_EXCEPTION_CLAUSE_FILTER)
7660-
clause_args.end_at_ip = (const guint16*)clause_args.start_with_ip + 0xffffff;
7661-
else
7667+
if (clause_type == MONO_EXCEPTION_CLAUSE_NONE || clause_type == MONO_EXCEPTION_CLAUSE_FILTER) {
7668+
/* Run until the end */
7669+
clause_args.end_at_ip = NULL;
7670+
clause_args.run_until_end = TRUE;
7671+
} else {
76627672
clause_args.end_at_ip = (const guint16*)ei->data.handler_end;
7673+
}
76637674
clause_args.exec_frame = &frame;
76647675

76657676
if (clause_type == MONO_EXCEPTION_CLAUSE_NONE || clause_type == MONO_EXCEPTION_CLAUSE_FILTER)

0 commit comments

Comments
 (0)