Refine AOT exception check when function return (#1752)

Refine AOT exception check in the caller when returning from callee function,
remove the exception check instructions when hw bound check is enabled to
improve the performance: create guard page to trigger signal handler when
exception occurs.
This commit is contained in:
Wenyong Huang
2022-11-30 20:18:28 +08:00
committed by GitHub
parent 7cb1ebc771
commit ce3458da99
8 changed files with 163 additions and 50 deletions

View File

@ -56,6 +56,12 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
#endif
#endif
#ifdef OS_ENABLE_HW_BOUND_CHECK
if (!(exec_env->exce_check_guard_page =
os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE)))
goto fail5;
#endif
exec_env->module_inst = module_inst;
exec_env->wasm_stack_size = stack_size;
exec_env->wasm_stack.s.top_boundary =
@ -76,6 +82,12 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
return exec_env;
#ifdef OS_ENABLE_HW_BOUND_CHECK
fail5:
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
wasm_cluster_destroy_exenv_status(exec_env->current_status);
#endif
#endif
#if WASM_ENABLE_THREAD_MGR != 0
#if WASM_ENABLE_DEBUG_INTERP != 0
fail4:
@ -96,6 +108,9 @@ fail1:
void
wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
{
#ifdef OS_ENABLE_HW_BOUND_CHECK
os_munmap(exec_env->exce_check_guard_page, os_getpagesize());
#endif
#if WASM_ENABLE_THREAD_MGR != 0
os_mutex_destroy(&exec_env->wait_lock);
os_cond_destroy(&exec_env->wait_cond);

View File

@ -137,6 +137,8 @@ typedef struct WASMExecEnv {
#ifdef OS_ENABLE_HW_BOUND_CHECK
WASMJmpBuf *jmpbuf_stack_top;
/* One guard page for the exception check */
uint8 *exce_check_guard_page;
#endif
#if WASM_ENABLE_MEMORY_PROFILING != 0
@ -199,7 +201,8 @@ wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size)
the outs area contains const cells, its size may be larger than current
frame size, we should check again before putting the function arguments
into the outs area. */
if (addr + size * 2 > exec_env->wasm_stack.s.top_boundary) {
if (size * 2
> (uint32)(uintptr_t)(exec_env->wasm_stack.s.top_boundary - addr)) {
/* WASM stack overflow. */
return NULL;
}

View File

@ -185,6 +185,12 @@ runtime_signal_handler(void *sig_addr)
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
#endif
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) {
bh_assert(wasm_get_exception(module_inst));
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
}
}
#else
@ -1435,6 +1441,17 @@ wasm_runtime_get_user_data(WASMExecEnv *exec_env)
return exec_env->user_data;
}
#ifdef OS_ENABLE_HW_BOUND_CHECK
void
wasm_runtime_access_exce_check_guard_page()
{
if (exec_env_tls && exec_env_tls->handle == os_self_thread()) {
uint32 page_size = os_getpagesize();
memset(exec_env_tls->exce_check_guard_page, 0, page_size);
}
}
#endif
WASMType *
wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
uint32 module_type)

View File

@ -554,6 +554,12 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data);
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_user_data(WASMExecEnv *exec_env);
#ifdef OS_ENABLE_HW_BOUND_CHECK
/* Access exception check guard page to trigger the signal handler */
void
wasm_runtime_access_exce_check_guard_page();
#endif
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_call_wasm(WASMExecEnv *exec_env,