Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pop LMF frames in exception handlers on wasm, since the normal pop LMF code might not get executed in case of an exception. #47144

Merged
merged 2 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/mono/mono/metadata/jit-icall-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ MONO_JIT_ICALL (mini_llvmonly_resolve_iface_call_gsharedvt) \
MONO_JIT_ICALL (mini_llvmonly_resolve_vcall_gsharedvt) \
MONO_JIT_ICALL (mini_llvmonly_throw_nullref_exception) \
MONO_JIT_ICALL (mini_llvmonly_throw_aot_failed_exception) \
MONO_JIT_ICALL (mini_llvmonly_pop_lmf) \
MONO_JIT_ICALL (mono_amd64_resume_unwind) \
MONO_JIT_ICALL (mono_amd64_start_gsharedvt_call) \
MONO_JIT_ICALL (mono_amd64_throw_corlib_exception) \
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/aot-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "mini.h"

/* Version number of the AOT file format */
#define MONO_AOT_FILE_VERSION 179
#define MONO_AOT_FILE_VERSION 180

#define MONO_AOT_TRAMP_PAGE_SIZE 16384

Expand Down
12 changes: 12 additions & 0 deletions src/mono/mono/mini/llvmonly-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,3 +815,15 @@ mini_llvmonly_throw_aot_failed_exception (const char *name)
g_free (msg);
mono_llvm_throw_exception ((MonoObject*)ex);
}

/*
* mini_llvmonly_pop_lmf:
*
* Pop LMF off the LMF stack.
*/
void
mini_llvmonly_pop_lmf (MonoLMF *lmf)
{
if (lmf->previous_lmf)
mono_set_lmf (lmf->previous_lmf);
vargaz marked this conversation as resolved.
Show resolved Hide resolved
}
2 changes: 2 additions & 0 deletions src/mono/mono/mini/llvmonly-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ G_EXTERN_C void mini_llvmonly_throw_nullref_exception (void);

G_EXTERN_C void mini_llvmonly_throw_aot_failed_exception (const char *name);

G_EXTERN_C void mini_llvmonly_pop_lmf (MonoLMF *lmf);

#endif
12 changes: 12 additions & 0 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -8052,6 +8052,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b

#ifdef TARGET_WASM
if (common_call && needs_stack_walk)
/* If an exception is thrown, the LMF is popped by a call to mini_llvmonly_pop_lmf () */
emit_pop_lmf (cfg);
#endif

Expand Down Expand Up @@ -11669,6 +11670,17 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
mono_get_got_var (cfg);
#endif

#ifdef TARGET_WASM
if (cfg->lmf_var) {
// mini_llvmonly_pop_lmf () might be called before emit_push_lmf () so initialize the LMF
cfg->cbb = init_localsbb;
EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
int lmf_reg = ins->dreg;

EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_IMM, lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0);
}
#endif

if (cfg->method == method && cfg->got_var)
mono_emit_load_got_addr (cfg);

Expand Down
18 changes: 18 additions & 0 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -4700,6 +4700,24 @@ emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBloc
mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
}

#ifdef TARGET_WASM
lambdageek marked this conversation as resolved.
Show resolved Hide resolved
if (ctx->cfg->lmf_var) {
LLVMValueRef callee;
LLVMValueRef args [1];
LLVMTypeRef sig = LLVMFunctionType1 (LLVMVoidType (), ctx->module->ptr_type, FALSE);

/*
* There might be an LMF on the stack inserted to enable stack walking, see
* method_needs_stack_walk (). If an exception is thrown, the LMF popping code
* is not executed, so do it here.
*/
g_assert (ctx->addresses [ctx->cfg->lmf_var->dreg]);
callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_llvmonly_pop_lmf));
args [0] = convert (ctx, ctx->addresses [ctx->cfg->lmf_var->dreg], ctx->module->ptr_type);
emit_call (ctx, bb, &ctx->builder, callee, args, 1);
}
#endif

LLVMBuilderRef handler_builder = create_builder (ctx);
LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
LLVMPositionBuilderAtEnd (handler_builder, target_bb);
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4913,6 +4913,7 @@ register_icalls (void)
register_icall (mini_llvmonly_init_delegate_virtual, mono_icall_sig_void_object_object_ptr, TRUE);
register_icall (mini_llvmonly_throw_nullref_exception, mono_icall_sig_void, TRUE);
register_icall (mini_llvmonly_throw_aot_failed_exception, mono_icall_sig_void_ptr, TRUE);
register_icall (mini_llvmonly_pop_lmf, mono_icall_sig_void_ptr, TRUE);

register_icall (mono_get_assembly_object, mono_icall_sig_object_ptr, TRUE);
register_icall (mono_get_method_object, mono_icall_sig_object_ptr, TRUE);
Expand Down