Skip to content

Commit

Permalink
[mono][interp] Fix execution of clauses from il state when tiering is…
Browse files Browse the repository at this point in the history
… enabled

When invoking these clauses we obtained the InterpMethod from the MonoMethod* and make use of the jit info stored during frame unwinding. However, the method might have been tiered up since storing the jit info, so the native offsets stored there will no longer be relative to the optimized imethod. Fetch again the MonoJitInfo* from the imethod that we will be executing.
  • Loading branch information
BrzVlad committed May 17, 2022
1 parent 0fabe0e commit 20f0eeb
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/mono/mono/mini/ee.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ typedef gpointer MonoInterpFrameHandle;
MONO_EE_CALLBACK (void, get_resume_state, (const MonoJitTlsData *jit_tls, gboolean *has_resume_state, MonoInterpFrameHandle *interp_frame, gpointer *handler_ip)) \
MONO_EE_CALLBACK (gboolean, run_finally, (StackFrameInfo *frame, int clause_index, gpointer handler_ip, gpointer handler_ip_end)) \
MONO_EE_CALLBACK (gboolean, run_filter, (StackFrameInfo *frame, MonoException *ex, int clause_index, gpointer handler_ip, gpointer handler_ip_end)) \
MONO_EE_CALLBACK (gboolean, run_clause_with_il_state, (gpointer il_state, int clause_index, gpointer handler_ip, gpointer handler_ip_end, MonoObject *ex, gboolean *filtered, MonoExceptionEnum clause_type)) \
MONO_EE_CALLBACK (gboolean, run_clause_with_il_state, (gpointer il_state, int clause_index, MonoObject *ex, gboolean *filtered)) \
MONO_EE_CALLBACK (void, frame_iter_init, (MonoInterpStackIter *iter, gpointer interp_exit_data)) \
MONO_EE_CALLBACK (gboolean, frame_iter_next, (MonoInterpStackIter *iter, StackFrameInfo *frame)) \
MONO_EE_CALLBACK (MonoJitInfo*, find_jit_info, (MonoMethod *method)) \
Expand Down
3 changes: 1 addition & 2 deletions src/mono/mono/mini/interp-stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ stub_run_filter (StackFrameInfo *frame, MonoException *ex, int clause_index, gpo
}

static gboolean
stub_run_clause_with_il_state (gpointer il_state, int clause_index, gpointer handler_ip, gpointer handler_ip_end, MonoObject *ex,
gboolean *filtered, MonoExceptionEnum clause_type)
stub_run_clause_with_il_state (gpointer il_state, int clause_index, MonoObject *ex, gboolean *filtered)
{
g_assert_not_reached ();
}
Expand Down
21 changes: 17 additions & 4 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7477,8 +7477,7 @@ interp_run_filter (StackFrameInfo *frame, MonoException *ex, int clause_index, g

/* Returns TRUE if there is a pending exception */
static gboolean
interp_run_clause_with_il_state (gpointer il_state_ptr, int clause_index, gpointer handler_ip, gpointer handler_ip_end,
MonoObject *ex, gboolean *filtered, MonoExceptionEnum clause_type)
interp_run_clause_with_il_state (gpointer il_state_ptr, int clause_index, MonoObject *ex, gboolean *filtered)
{
MonoMethodILState *il_state = (MonoMethodILState*)il_state_ptr;
MonoMethodSignature *sig;
Expand All @@ -7493,6 +7492,11 @@ interp_run_clause_with_il_state (gpointer il_state_ptr, int clause_index, gpoint
g_assert (sig);

imethod = mono_interp_get_imethod (il_state->method);
if (!imethod->transformed) {
// In case method is in process of being tiered up, make sure it is compiled
mono_interp_transform_method (imethod, context, error);
mono_error_assert_ok (error);
}

orig_sp = sp_args = sp = (stackval*)context->stack_pointer;

Expand Down Expand Up @@ -7545,11 +7549,20 @@ interp_run_clause_with_il_state (gpointer il_state_ptr, int clause_index, gpoint
}

memset (&clause_args, 0, sizeof (FrameClauseArgs));
clause_args.start_with_ip = (const guint16*)handler_ip;
MonoJitExceptionInfo *ei = &imethod->jinfo->clauses [clause_index];
MonoExceptionEnum clause_type = ei->flags;
// For filter clauses, if filtered is set, then we run the filter, otherwise we run the catch handler
if (clause_type == MONO_EXCEPTION_CLAUSE_FILTER && !filtered)
clause_type = MONO_EXCEPTION_CLAUSE_NONE;

if (clause_type == MONO_EXCEPTION_CLAUSE_FILTER)
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
clause_args.end_at_ip = (const guint16*)handler_ip_end;
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
8 changes: 3 additions & 5 deletions src/mono/mono/mini/mini-exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2011,7 +2011,7 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt
if (frame.type == FRAME_TYPE_IL_STATE) {
if (mono_trace_is_enabled () && mono_trace_eval (method))
g_print ("EXCEPTION: filter clause found in AOTed code, running it with the interpreter.\n");
gboolean res = mini_get_interp_callbacks ()->run_clause_with_il_state (frame.il_state, i, ei->data.filter, NULL, ex_obj, &filtered, MONO_EXCEPTION_CLAUSE_FILTER);
gboolean res = mini_get_interp_callbacks ()->run_clause_with_il_state (frame.il_state, i, ex_obj, &filtered);
// FIXME:
g_assert (!res);
} else if (ji->is_interp) {
Expand Down Expand Up @@ -2574,7 +2574,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
if (frame.type == FRAME_TYPE_IL_STATE) {
if (mono_trace_is_enabled () && mono_trace_eval (method))
g_print ("EXCEPTION: finally/fault clause found in AOTed code, running it with the interpreter.\n");
mini_get_interp_callbacks ()->run_clause_with_il_state (frame.il_state, i, ei->handler_start, ei->data.handler_end, NULL, NULL, MONO_EXCEPTION_CLAUSE_FINALLY);
mini_get_interp_callbacks ()->run_clause_with_il_state (frame.il_state, i, NULL, NULL);
} else if (in_interp) {
gboolean has_ex = mini_get_interp_callbacks ()->run_finally (&frame, i, ei->handler_start, ei->data.handler_end);
if (has_ex) {
Expand Down Expand Up @@ -3579,10 +3579,8 @@ mini_llvmonly_resume_exception_il_state (MonoLMF *lmf, gpointer info)
/* Pop the LMF frame so the caller doesn't have to do it */
mono_set_lmf ((MonoLMF *)(((gsize)lmf->previous_lmf) & ~3));

MonoJitInfo *ji = jit_tls->resume_state.ji;
int clause_index = jit_tls->resume_state.clause_index;
MonoJitExceptionInfo *ei = &ji->clauses [clause_index];
gboolean r = mini_get_interp_callbacks ()->run_clause_with_il_state (il_state, clause_index, ei->handler_start, NULL, ex_obj, NULL, MONO_EXCEPTION_CLAUSE_NONE);
gboolean r = mini_get_interp_callbacks ()->run_clause_with_il_state (il_state, clause_index, ex_obj, NULL);
if (r)
/* Another exception thrown, continue unwinding */
mono_llvm_cpp_throw_exception ();
Expand Down

0 comments on commit 20f0eeb

Please sign in to comment.