Skip to content

Commit

Permalink
[release/7.0] [mono][interp] Fix an issue with deopt and interpreter …
Browse files Browse the repository at this point in the history
…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 <vargaz@gmail.com>
  • Loading branch information
github-actions[bot] and vargaz authored Nov 10, 2022
1 parent 00816bf commit d933222
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct FrameClauseArgs {
const guint16 *end_at_ip;
/* Frame that is executing this clause */
InterpFrame *exec_frame;
gboolean run_until_end;
};

/*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -7067,15 +7075,15 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;

MINT_IN_CASE(MINT_TIER_ENTER_METHOD) {
frame->imethod->entry_count++;
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT)
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT && !clause_args)
ip = mono_interp_tier_up_frame_enter (frame, context);
else
ip++;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_TIER_PATCHPOINT) {
frame->imethod->entry_count++;
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT)
if (frame->imethod->entry_count > INTERP_TIER_ENTRY_LIMIT && !clause_args)
ip = mono_interp_tier_up_frame_patchpoint (frame, context, ip [1]);
else
ip += 2;
Expand Down Expand Up @@ -7656,10 +7664,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)
Expand Down

0 comments on commit d933222

Please sign in to comment.