Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-11-10 21:37:18 +0300
committerGitHub <noreply@github.com>2022-11-10 21:37:18 +0300
commitd933222dc9c9324694a95049279674b2e502d230 (patch)
treeec2af1a0ff770ae175f60bcb5e449e3beb2c2b30
parent00816bfb6f041fecab48ca9b467c5caba1b8ef3d (diff)
[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 https://github.com/dotnet/runtime/issues/76134 https://github.com/dotnet/runtime/issues/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>
-rw-r--r--src/mono/mono/mini/interp/interp.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c
index b89f8a7a181..89a0b5962e3 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
@@ -7067,7 +7075,7 @@ 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++;
@@ -7075,7 +7083,7 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); 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;
@@ -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)